This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: [dax@gurulabs.com: PATCH: `__norestrict' type qualifier (fwd)]


Richard Stallman wrote:
> Since this really is a new feature, we have to judge it as one; it
> needs to be clear to document, and reliable to use.  I don't know
> whether this feature can be described and implemented reliably, but I
> think that should be possible.  "Apply the same rules that apply to
> char *" seems like a clear basis for the specification; and as long as
> GCC reliably implements the ISO C aliasing rules for char *, it should
> be able to implement this with equal reliability.

"Apply the same rules that apply to char *" gives us a sensible rule,
for the type alias tests in the compiler.  I think it is quite a clear
rule.

For the user, we should take care what we promise.  As the sprinkle of
mb(), rmb() and wmb() through Linux shows, and a recent misunderstanding
of the barrier properties of `volatile', C memory ordering rules in
general can be confusing.

ISO C doesn't talk about type aliasing.  It talks about permitted access
through pointers.  It doesn't define what happens when one object is
accessed through another pointer type.  Obviously we know what kind of
code is preferred:

   1. fast;
   2. shouldn't make any special effort for unaligned data;
   3. the read/write operation should use the machine operation of the
      cast-to type, not the cast-from type with conversion in registers.

A naive definition in memcpy() terms did not satisfy 1 or 2 for some
types.  We have an example of code that gives the wrong answer if 3 is
not satisfied.

After a few iterations I came up with this, which everyone was too busy
to disagree with :-)

Oh, to the compiler implementors: I think the implementation is exactly
the rule "Apply the same rules that apply to char *" :-)

                          ------------------

The C9X draft defines alignment already:

       3.1
       [#1] alignment
       requirement that objects of a particular type be located  on
       storage   boundaries  with  addresses  that  are  particular
       multiples of a byte address

Conversions between different pointer types are defined thus (though
access through the wrong pointer type is undefined):

       6.3.2.3  Pointers
       [#7]  A  pointer  to  an  object  or  incomplete type may be
       converted to a pointer to a different object  or  incomplete
       type.   If the resulting pointer is not correctly aligned50)
       for  the  pointed-to  type,  the  behavior   is   undefined.
       Otherwise,  when  converted  back  again,  the  result shall
       compare equal to the original pointer.  When a pointer to an
       object  is  converted  to a pointer to a character type, the
       result points to the lowest addressed byte  of  the  object.

That brings on a new proposed definition.  Remember this is all so GCC can
generate good code, that's our excuse for discussing it on this list... ;-)

I think this fixes every problem raised so far:

    For conversion to and from other pointer types, pointers of type
    `__norestrict B *', for all B, are subject to the same guarantees and
    restrictions as pointers of type `B *'.  See 6.3.2.3 [#7].

    In particular, if the result of converting a pointer to `__norestrict B
    *' is not correctly aligned for the type B, the behaviour is undefined.

    Reading through a pointer of type `__norestrict B *' shall have the
    same, implementation-defined behaviour as converting the pointer to
    type `const char *', copying sizeof B characters from that address into
    field `a' of a temporary of type `union { char a [sizeof B]; B b; }',
    and then reading field `b'.

    Writing through a pointer of type `__norestrict B *' shall have the
    same, implementation-defined behaviour as writing to field `b' of a
    temporary of type `union { char a [sizeof B]; B b; }', converting the
    pointer to type `char *', and then copying sizeof B characters to that
    address from field `a'.

    The order of character copies is not defined -- they may occur
    simultaneously, independently or in any combination.  A volatile
    qualification on B does not change this.  A const qualification is
    honoured by disallowing writes in the usual way.


-- Jamie

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]