This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: module level flags
On Sun, Sep 29, 2002 at 05:40:01AM -0400, Robert Dewar wrote:
> <<In the original code, the type-based aliasing rules permit the
> compiler to assume that assignment to ppT does not modify list
> EVEN THOUGH IT IS OBVIOUS TO A HUMAN THAT IT DOES.
> >>
>
> Zack, as far as I can tell, the compiler was not only "working as designed",
> but is in fact correctly implementing the language. A human may think
> that this code should work, but that just comes from not knowing the language
> properly. A lot of people have a low level semantic model that unfortunately
> does not correspond to the actual semantics.
>
> I know you know this, but the wording of your message could still leave
> the impression that the compiler was somehow malfunctoining, which is
> not the case.
Yes, my wording was poorly chosen. I did mean to convey that the
current behavior is a correct implementation of the language standard.
For reference, I believe the relevant section of C99 is section 6.5,
paragraphs 6 and 7, and associated footnotes:
6 The effective type of an object for an access to its stored value
is the declared type of the object, if any.(72) If a value is
stored into an object having no declared type through an lvalue
having a type that is not a character type, then the type of the
lvalue becomes the effective type of the object for that access
and for subsequent accesses that do not modify the stored value.
If a value is copied into an object having no declared type using
memcpy or memmove, or is copied as an array of character type,
then the effective type of the modified object for that access and
for subsequent accesses that do not modify the value is the
effective type of the object from which the value is copied, if it
has one. For all other accesses to an object having no declared
type, the effective type of the object is simply the type of the
lvalue used for the access.
7 An object shall have its stored value accessed only by an lvalue
expression that has one of the following types:(73)
-- a type compatible with the effective type of the object,
-- a qualified version of a type compatible with the effective
type of the object,
-- a type that is the signed or unsigned type corresponding to
the effective type of the object,
-- a type that is the signed or unsigned type corresponding to a
qualified version of the effective type of the object,
-- an aggregate or union type that includes one of the
aforementioned types among its members (including,
recursively, a member of a subaggregate or contained union), or
-- a character type.
footnotes
72) Allocated objects have no declared type.
73) The intent of this list is to specify those circumstances in
which an object may or may not be aliased.
The code under discussion took the form
T foo (T arg)
{
U *ptr = (U *) &arg;
*ptr = new_value();
return arg;
}
where T and U are incompatible types. The construct clearly does not
satisfy any of the possibilities in 6.5p7, so undefined behavior
results.
Bruce argues that since it is obvious what 'ptr' points to, that
information should override the rules in 6.5p7. The trouble with this
argument is defining what qualifies as obvious. Data flow analysis
can determine this sort of fact, with difficulty ranging from easy (as
in this example) to undecidable (in the general case). The C
committee decided not to make the correctness of a program depend on
how clever the optimizer is. IMHO, this was the right decision from
their point of view.
I'd also like to point out that we have had this argument before. See
e.g. http://gcc.gnu.org/ml/gcc/1999-09/msg00316.html and the very long
thread which followed, and please notice that the subject line is
"type based aliasing *again*" (emphasis mine).
zw