public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jamie Lokier <jamie.lokier@cern.ch>
To: Richard Stallman <rms@gnu.org>
Cc: gcc@gcc.gnu.org
Subject: Re: [dax@gurulabs.com: PATCH: `__norestrict' type qualifier (fwd)]
Date: Sun, 12 Sep 1999 12:29:00 -0000	[thread overview]
Message-ID: <19990912212818.C26524@pcep-jamie.cern.ch> (raw)
In-Reply-To: <199909120800.EAA04240@psilocin.gnu.org>

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

WARNING: multiple messages have this Message-ID
From: Jamie Lokier <jamie.lokier@cern.ch>
To: Richard Stallman <rms@gnu.org>
Cc: gcc@gcc.gnu.org
Subject: Re: [dax@gurulabs.com: PATCH: `__norestrict' type qualifier (fwd)]
Date: Thu, 30 Sep 1999 18:02:00 -0000	[thread overview]
Message-ID: <19990912212818.C26524@pcep-jamie.cern.ch> (raw)
Message-ID: <19990930180200.1mBHdesVmCRvAyRaqEsyFnds4veMSHWLintMNo8avrs@z> (raw)
In-Reply-To: <199909120800.EAA04240@psilocin.gnu.org>

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

  reply	other threads:[~1999-09-12 12:29 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1999-09-12  0:51 Richard Stallman
1999-09-12 12:29 ` Jamie Lokier [this message]
1999-09-14  8:34   ` patl
1999-09-14  8:38     ` Jamie Lokier
1999-09-15  2:02       ` Jeffrey A Law
1999-09-30 18:02         ` Jeffrey A Law
1999-09-30 18:02       ` Jamie Lokier
1999-09-30 18:02     ` Patrick J. LoPresti
1999-09-30 18:02   ` Jamie Lokier
1999-09-30 18:02 ` Richard Stallman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=19990912212818.C26524@pcep-jamie.cern.ch \
    --to=jamie.lokier@cern.ch \
    --cc=gcc@gcc.gnu.org \
    --cc=rms@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).