why prefix increment is faster than postfix increment?

B

Branimir Maksimovic

Branimir Maksimovic said:
Flash Gordon said:
Branimir said:
Christian Bau wrote:

William Hughes wrote:

Branimir Maksimovic wrote:

Mark McIntyre wrote:

On 26 Oct 2005 09:00:34 -0700, in comp.lang.c , "Branimir
Maksimovic"

Keith Thompson wrote:

This is important in regard of what makes original poster conclude
that memcpy(&x,&y,sizeof(x)) should be always faster or equal then
memcpy(&x,&y,sizeof(x)-1). ^^^^^^^^^^^^^^^^^^^^^^^^^

Christian Bau (who was not the original poster) did not conclude this.
His point was that memcpy(&x,&y,sizeof(x)) *could* be faster
than memcpy(&x,&y,sizeof(x)-1).

Clearly memcpy parameter is not about number of copy operations, and
in this respect his conclusion is invalid, because if
memcpy(&x,&y,sizeof(x)-1) does not produce trap value, ^^^^^^^^^^^^^^^^^^^^^^^^^
implementation can use load register, store register,

Nope, you have to preseve the last byte.

What byte?
Implementation can do anything that does not change observable
behavior. Since you have stored something that is not
valid double object, last byte would not change observable behavior, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
because using x as a double further in program
produces undefined behavior anyway.

Example:

double x, y;
x = 0.0; y = 1.0 / 3.0;

((unsigned char *) &x) [sizeof (x) - 1] = 79;
memcpy (&x, &y, sizeof (x) - 1);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Looks the same to me.

Oh original example which started whole discussion was lost. Sorry.
how about original example with:
memcpy (&x, &y, sizeof (x));

Christian Bau was responding to a bit about memcpy (&x, &y, sizeof (x) -
1); and his post looks entirely correct to me.
if (((unsigned char *) &x) [sizeof (x) - 1] != 79)
printf ("This implementation is broken!\n");

I stored the number 79 into the last byte of x. The memcpy is not
allowed to overwrite it, so it must contain the value 79 after the call
to memcpy. There is no undefined behavior. There might be undefined
behavior if I _would_ use x as a double, but I don't, so there is no
undefined behavior.

Come on, this has completely different semantics then original example.

This thread has been talking about both sizeof (x) and sizeof (x) - 1 for
ages.
You have created valid unsigned char object at a given address
and dropped memcpy with sizeof(x). Stop playing around.

All bytes can always be read as unsigned char values, An alternative
example would have been taking a copy of the byte that memcpy is not
allowed to change and verifying afterwards that it had not changed.

Even as I said that will shut up, couldn't resist to this one.
This is not enough to trick implementation to force preservation of said
byte.
Implementation can simply replace
if (((unsigned char *) &x) [sizeof (x) - 1] != 79)
with if (0) and change the byte without problem.
Since everything happens at same scope, this does not affect observable
behavior and here we are again :); one must to do something like this
instead:

double x,y;
((unsigned char *) &x) [sizeof (x) - 1] = 79;
memcpy (&x, &y, sizeof (x) - 1);
void foo(unsigned char*); /* some external function not visible in this
translation unit */
foo( ((unsigned char *) &x) + sizeof (x) - 1 );

Now implementation must preserve that byte because it does not knows
what happens in "foo". :)

But in case that we don't initialize the byte, trick is little bit
different:
double x,y;
unsigned char* p= ((unsigned char *) &x) +sizeof (x) - 1;
unsigned char t = *p;
memcpy (&x, &y, sizeof (x) - 1);
unsigned char foo(unsigned char*); /* some external function not visible
in this translation unit */
assert(foo(p)==t); /* this forces implementation to preserve
the byte since foo may or may not return same value */

But I missed one major point. memcpy can be completely optimised out
since that does not change behavior of program.
So......
double x,y;
unsigned char* p= ((unsigned char *) &x) +sizeof (x) - 1;
unsigned char t = *p;
memcpy (&x, &y, sizeof (x) - 1);
unsigned char foo(unsigned char*); /* some external function not visible
in this translation unit */
void bar(double *,double*); /* external */
bar(&x,&y); /* this finally forces compiler to actually *perform* memcpy
because it does not knows if corresponding chars would
be checked for equality */
assert(foo(p)==t); /* this forces implementation to preserve
the byte since foo may or may not return same value */

Finally I think that I got it right. Perhaps not? compiler can always
outsmart programmer :)
 
C

Christian Bau

"peter koch said:
William Hughes skrev:
peter said:
William Hughes skrev:
[snip]
The undefined behaviour comes from reading from the uninitialized
variable y.

This is silly. Under this interpretation the code snippet

a = b;

invokes undefined behaviour. There is a limit to pedantry
even in comp.lang.c.

This might be pedantic, yes. But certainly this is according to the
standard and let's not begin to question its validity.
[An interesting question. Does reading an uninitialized variable
as a sequence of unsigned char invoke undefined behaviour]

My understanding is that this is the case. Reading uninitialized chars
might not invoke undefined behaviour, but the data was read from a
double not a char and in this case (again so far as i understand the
standard), this is undefined behaviour.
Nonsense.

Since this was meant to show how the execution speed of an
operation defined in abstract terms can depend on the implementation,
and
alignment issues are certainly implementation dependent.
your remark is flat out wrong. You did check some of the
context before replying, didn't you?

I did. Did you read the subject line? The reply should be related to
the subject and in that context Baus example is useless.

Ok, I'll change the subject line to "koch is clueless", if that pleases
you.
What the poster did or did not say does not matter. I was explaining my
own reasons for considering the program non-conforming.

Which were complete - excuse me - bullshit.
 
C

Christian Bau

"Branimir Maksimovic said:
don't take this as C or C++ expression :)

Perfectly legal expression in C and C++. Interestingly, it has a value
of 1 if and only if all four sizeof's have a value of one, while

sizeof(long) == sizeof(int) == sizeof(short) == sizeof(char)

has a value of 1 if long and int have the same size, and short has size
1.
 
M

Michael Wojcik

The reply should be related to the subject

Who, besides yourself, promulgates this rule, pray tell? And is it
not rather hypocritical, in your case, since it applies equally to
all of your contributions to this subthread?
and in that context Baus example is useless.

Fortunately, that "context" is no more than your own odd prejudice,
and of no weight in the argument. Christian Bau was responding in a
subthread about the possible relative speeds of operations on
different numbers of objects. Your curious (and sudden) insistence
on confining replies strictly to the topic named in the subject line
says nothing about the relevance of his contribution for everyone
else participating in the discussion.

It's clear that having failed to raise meaningful technical
objections to Christian's argument, you are now resorting to, in
effect, argumentum ad verecundiam - asking that it be rejected
because it is somehow inappropriate. I'm afraid that's not very
persuasive either.
 
J

Jordan Abel

Perfectly legal expression in C and C++. Interestingly, it has a
value of 1 if and only if all four sizeof's have a value of one,
while

sizeof(long) == sizeof(int) == sizeof(short) == sizeof(char)

has a value of 1 if long and int have the same size, and short has
size 1.

yes, but its meaning as a C expression is not the meaning that was
intended by it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top