Aliasing and optimization

L

ln myshkin

On a platform where sizeof (void) != sizeof(int), given code like the following:

#include <stdio.h>

union
{
void* p;
int i;
} u;

void f()
{
int* pi = & u.i;
(*pi)++;
u.p = NULL;
}

is the compiler allowed to emit assembly corresponding to:

void f()
{
int* pi = & u.i;
u.p = NULL; // reordered
(*pi)++;
}

and is it guaranteed that NULL-ing u.p results in u.i == 0?
i.e:

u.p = NULL;
assert(u.i == 0);

Thanks in advance.
 
M

Martin Ambuhl

ln said:
On a platform where sizeof (void) != sizeof(int), given code like the following:

void is an incomplete type that cannot be completed.
It is not valid to use the operator sizeof on (void).
sizeof(void) is meaningless, and if anything that follows depends on it,
the that too is meaningless. For your question below it is not
sizeof(void) which is used, but sizeof(void *), which is just fine.
There is a huge difference between a pointer-to-void and void.
#include <stdio.h>

union
{
void* p;
int i;
} u;

void f()
{
int* pi = & u.i;
(*pi)++;
u.p = NULL;
}

The effect of the above is to make u.p a null pointer; anything done to
u.i before that produces nothing meaningful.
is the compiler allowed to emit assembly corresponding to:

void f()
{
int* pi = & u.i;
u.p = NULL; // reordered
(*pi)++;
}

Of course not. The effect is quite obviously other than to make u.p
null. NULL might be 0, or it might be (void &)0. Don't assume that the
bit pattern resulting from that assignment is the same as (int)0.
Whatever NULL is, assuming accessing it in this way is licit, the result
cannot be the same null pointer constant, can it?
and is it guaranteed that NULL-ing u.p results in u.i == 0?

NULL

Of course not. Only the value of the last member into which something
is stored has meaning. When the last member to have a value assigned to
it is u.p, reading u.i yields nothing meaningful.

Write this on your forehead: "Only one member of a union can contain a
value at a particular time." Your C text should have a sentence similar
to that. An example of such a statement is in H&S 5.7.4 (Mis)using
Union Types: "Unions are used in a nonportable fashion any time a union
component is reference when the last assignment to the union was not
through the same component."

Tricks involving assigning values to one member and attempting to access
the result of such assignment through another member are tricks that
fledgling programmers should grow out of.
 
F

Flash Gordon

ln said:
On a platform where sizeof (void) != sizeof(int), given code like the following:

#include <stdio.h>

union
{
void* p;
int i;
} u;

void f()
{
int* pi = & u.i;
(*pi)++;
u.p = NULL;
}

is the compiler allowed to emit assembly corresponding to:

void f()
{
int* pi = & u.i;
u.p = NULL; // reordered
(*pi)++;
}

No, because the last member written to was u.p so that value is
guaranteed to be stored.
and is it guaranteed that NULL-ing u.p results in u.i == 0?
i.e:

u.p = NULL;

No for at least two reasons. One is that a null pointer is not
guaranteed to be all bits zero, and there is at least one implementation
where it is not. The other is that you are only allowed to read from a
union using the member (or a pointer to it) last used to write to it
(you might be allowed to read it as an unsigned char member as well, I
can't remember).
 
L

ln myshkin

void is an incomplete type that cannot be completed.
It is not valid to use the operator sizeof on (void).
sizeof(void) is meaningless, and if anything that follows depends on it,
the that too is meaningless. For your question below it is not
sizeof(void) which is used, but sizeof(void *), which is just fine.
There is a huge difference between a pointer-to-void and void.

Yes, I forgot a star. It should have been sizeof(void*)
The effect of the above is to make u.p a null pointer; anything done to
u.i before that produces nothing meaningful.


Of course not. The effect is quite obviously other than to make u.p
null. NULL might be 0, or it might be (void &)0. Don't assume that the
bit pattern resulting from that assignment is the same as (int)0.
Whatever NULL is, assuming accessing it in this way is licit, the result
cannot be the same null pointer constant, can it?


NULL

Of course not. Only the value of the last member into which something
is stored has meaning. When the last member to have a value assigned to
it is u.p, reading u.i yields nothing meaningful.

Write this on your forehead: "Only one member of a union can contain a
value at a particular time." Your C text should have a sentence similar
to that. An example of such a statement is in H&S 5.7.4 (Mis)using
Union Types: "Unions are used in a nonportable fashion any time a union
component is reference when the last assignment to the union was not
through the same component."

Tricks involving assigning values to one member and attempting to access
the result of such assignment through another member are tricks that
fledgling programmers should grow out of.

Well I'm gathering reasons to explane a misbehaviour
in code (not mine) that only fail on certain platforms with
optimization enabled etc...
 
B

Ben Bacarisse

ln myshkin said:
On a platform where sizeof (void) != sizeof(int), given code like
the following:

I think you mean sizeof (void *). If you don't, then you need to say more.
union
{
void* p;
int i;
} u;

void f()
{
int* pi = & u.i;
(*pi)++;
u.p = NULL;
}

is the compiler allowed to emit assembly corresponding to:

void f()
{
int* pi = & u.i;
u.p = NULL; // reordered
(*pi)++;
}

Yes and no! Yes on very odd machines where, say, a void * has an
int's worth of padding bits at the "top" of the value. Yes also if
your real code (this looks like an illustration) has already invoked
undefined behaviour -- the optimiser may have taken that as permission
to do some very odd things.

But in general, no.
and is it guaranteed that NULL-ing u.p results in u.i == 0?

No. At the very least, my assumption that you mean void * and int are
not the same size means that the int could be bigger (there are other
reasons already pointer out).

What are you doing? There may be a portable way to do 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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,062
Latest member
OrderKetozenseACV

Latest Threads

Top