Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Is the aliasing rule symmetric?

Reply
Thread Tools

Is the aliasing rule symmetric?

 
 
Johannes Schaub (litb)
Guest
Posts: n/a
 
      01-21-2011
Posting my SO question to usenet:

Hello all. I had a discussion with someone on IRC and this question turned
up. We are allowed by the Standard to change an object of type `int` by a
`char` lvalue.

int a;
char *b = (char*) &a;
*b = 0;

Would we be allowed to do this in the opposite direction, if we know that
the alignment is fine?

The issue I'm seeing is that the aliasing rule does not cover the simple
case of the following, if one considers the aliasing rule as a non-symmetric
relation

int a;
a = 0;

The reason is, that each object contains a sequence of `sizeof(obj)`
`unsigned char` objects (called the "object representation"). If we change
the `int`, we will change some or all of those objects. However, the
aliasing rule only states we are allowed to change a `int` by an `char` or
`unsigned char`, but not the other way around. Another example

int a[1];
int *ra = a;
*ra = 0;

Only one direction is described by 3.10/15 ("An aggregate or union type that
includes..."), but this time we need the other way around ("A type that is
the element or non-static data member type of an aggregate...").

Is the other direction implied?
 
Reply With Quote
 
 
 
 
James Kanze
Guest
Posts: n/a
 
      01-21-2011
On Jan 21, 1:42 pm, "Johannes Schaub (litb)" <schaub-johan...@web.de>
wrote:
> Posting my SO question to usenet:


> Hello all. I had a discussion with someone on IRC and this
> question turned up. We are allowed by the Standard to change
> an object of type `int` by a `char` lvalue.


> int a;
> char *b = (char*) &a;
> *b = 0;


Up to a point. Formally, you have undefined behavior is you try
to access the value of a after this. Practically, the value of
a will depend on the architecture: setting a to 42, then doing
the modification above, will give different results on a Sparc
than on a PC.

> Would we be allowed to do this in the opposite direction, if
> we know that the alignment is fine?


Formally, no. Practically, if the alignment and the size are
sufficent, you should get the same results as a memcpy.

> The issue I'm seeing is that the aliasing rule does not cover the simple
> case of the following, if one considers the aliasing rule as a non-symmetric
> relation


> int a;
> a = 0;


I'm not sure I understand.

> The reason is, that each object contains a sequence of `sizeof(obj)`
> `unsigned char` objects (called the "object representation").


I'm not sure that "contains" is the right word. Each complete
object lives in a sequence of sizeof(obj) bytes of raw memory.

> If we change the `int`, we will change some or all of those
> objects. However, the aliasing rule only states we are allowed
> to change a `int` by an `char` or `unsigned char`, but not the
> other way around. Another example


The standard doesn't quite say that. It says that access to the
stored value of an object must be through an lvalue of the
object type, or through an lvalue of a char or unsigned char
type (plus a few other cases which don't concern us here).

> int a[1];
> int *ra = a;
> *ra = 0;


> Only one direction is described by 3.10/15 ("An aggregate or union type that
> includes..."), but this time we need the other way around ("A type that is
> the element or non-static data member type of an aggregate...").


> Is the other direction implied?


Certainly not. On some rare machines, int's may have trap
values, and the values in the bytes in an array of unsigned char
may correspond to one of those values. Replace int by float,
and most of the machines I know do have trap values.

There is one important exception: if you memcpy bytes out of
some type, you can memcpy those bytes back into an object of
that type, and you're guaranteed to get the same value, i.e.:

float in = 3.14159;
float out;
unsigned char buf[sizeof(float)];
memcpy(buf, &in, sizeof(float));
memcpy(&out, buf, sizeof(float));
std::cout << out << std::endl;

is guaranteed to output 3.14159, but

float out;
unsigned char buf[sizeof(float)];
random_fill(buf, buf + sizeof(float));
memcpy(&out, buf, sizeof(float));
std::cout << out << std::endl;

is undefined behavior, and might even crash.

--
James Kanze
 
Reply With Quote
 
 
 
 
Joshua Maurice
Guest
Posts: n/a
 
      01-21-2011
On Jan 21, 5:42*am, "Johannes Schaub (litb)" <schaub-johan...@web.de>
wrote:
> Posting my SO question to usenet:
>
> Hello all. I had a discussion with someone on IRC and this question turned
> up. We are allowed by the Standard to change an object of type `int` by a
> `char` lvalue.
>
> * * int a;
> * * char *b = (char*) &a;
> * * *b = 0;
>
> Would we be allowed to do this in the opposite direction, if we know that
> the alignment is fine?
>
> The issue I'm seeing is that the aliasing rule does not cover the simple
> case of the following, if one considers the aliasing rule as a non-symmetric
> relation
>
> * * int a;
> * * a = 0;
>
> The reason is, that each object contains a sequence of `sizeof(obj)`
> `unsigned char` objects (called the "object representation"). If we change
> the `int`, we will change some or all of those objects. However, the
> aliasing rule only states we are allowed to change a `int` by an `char` or
> `unsigned char`, but not the other way around. Another example
>
> * * int a[1];
> * * int *ra = a;
> * * *ra = 0;
>
> Only one direction is described by 3.10/15 ("An aggregate or union type that
> includes..."), but this time we need the other way around ("A type that is
> the element or non-static data member type of an aggregate...").
>
> Is the other direction implied?


I've done my best to educate myself on this topic, and as far as I can
tell, there is no consensus on some of the finer details. I've had a
thread up on comp.std.c++ for a few weeks no, with no replies.

In short, this is what I suggest:

When:
1- a constructor is called on a piece of memory (such as with operator
new, and placement new), or
2- you make a write to a piece of storage through an lvalue of a type
X with trivial initialization,
this ends the lifetime of any object which occupied that storage (and
any sub-object thereof), and it starts the lifetime of a new object of
type X at that storage. (Do not confuse "ending lifetime" with
"calling destructor". The destructors will not be called, but the
lifetimes of the objects will still end.) In practice, this is
basically required for all C code to work.

Any attempt to read an object through an lvalue of a type
"sufficiently different" than the effective type of the object (such
as reading an int object through a short lvalue) is undefined
behavior. An explicit exception is that you're always allowed to read
from or write to an object through a char or unsigned char lvalue.
Actually, this char and unsigned char allowance may be restricted to
POD types - I'm not quite sure, and no one else is either.

Thus, the following program does not have undefined behavior:
int main()
{ int a;
short* b = reinterpret_cast<short*>(&a);

a = 1;
*b = 2;
a = 3;
return a;
}

The following program does have undefined behavior.
int main()
{ int a;
short* b = reinterpret_cast<short*>(&a);

a = 1;
*b = 2;
//a = 3;
return a; //reading short object through int lvalue
}

Thus, try not to think about it as an aliasing rule. Think about it as
a rule which restricts the types of lvalues for which you may legally
access objects. This then allows a compiler to do optimization based
on aliasing analysis.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Is the aliasing rule symmetric? Johannes Schaub (litb) C Programming 110 02-16-2011 11:00 AM
Is the aliasing rule symmetric? Johannes Schaub (litb) C++ 68 02-06-2011 09:33 PM
how to add validation rule for url in the validation-rule.xml ,I added some thing like this but......... shailajabtech@gmail.com Java 0 10-12-2006 08:36 AM
Anti-aliasing GIF Images Kevin Bertman Java 4 11-29-2004 05:46 AM
LCD anti-aliasing in Java Tim Tyler Java 2 09-05-2003 09:01 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57