This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: PATCH: `__norestrict' type qualifier
- To: Linus Torvalds <torvalds at transmeta dot com>
- Subject: Re: PATCH: `__norestrict' type qualifier
- From: patl at curl dot com (Patrick J. LoPresti)
- Date: 19 Jul 1999 08:51:37 -0400
- Cc: Toon Moene <toon at moene dot indiv dot nluug dot nl>, Mark Mitchell <mark at codesourcery dot com>, egcs at egcs dot cygnus dot com
- References: <Pine.LNX.4.10.9907182314320.5178-100000@penguin.transmeta.com>
(Beware: I am going to pretend to be a Language Lawyer here.)
torvalds> "norestrict" does not magically make the pointer a
torvalds> "super-pointer", with X-ray vision and the power to leap
torvalds> tall buildings. If you want to write a strictly conforming
torvalds> program, you still have to follow all the other rules, and
torvalds> among those rules are that you cannot just do anything you
torvalds> want with pointers.
But this is precisely the point: A strictly conforming program can
*never* use pointers of different types to access the same memory
(with a few exceptions). When you try something like this, the result
is undefined (or "implementation-defined").
Let's make this completely clear: We are suggesting adding a keyword
which is a no-op for all conforming programs, whose only use is to
affect the behavior of *implementation-defined* constructs. From the
pedant's point of view, why does such a keyword belong in the standard
at all? An implementation is free to provide implementation-dependent
ways to affect implementation-dependent behavior.
torvalds> For example, here is a hypothetical strictly conforming
torvalds> program that uses the "norestrict" keyword (assuming it was
torvalds> to be made part of the standard), and that actually takes
torvalds> advantage of what norestrict guarantees without breaking
torvalds> any other rules:
[example snipped, where the return from "malloc" is cast to two
different types]
This is a weird example. I don't know how the standard deals with
"malloc", exactly... But it is precisely in giving a definition to
previously undefined constructs that you can run into trouble with the
standard's authors. The standard needs a precise definition of what
`norestrict' means, and it cannot just be by example. It could
require specifying an awful lot of currently-unspecified things in
order to precisely define the semantics that we want.
torvalds> PS. The other reason that the bit-wise argument does not
torvalds> make any sense at all is that a implementation is _already_
torvalds> required to make the bit-wise representation available
torvalds> regardless of "norestrict", simply because of the implied
torvalds> "norestrict" on any "char *" access:
Right, and thanks to this we can define `norestrict' precisely in
terms of sizeof() and char *. Then `norestrict' just becomes
shorthand for the (inlined) memcpy() trick.
But again, for *every* place we would ever use it, `norestrict' would
be shorthand for code with implementation-defined behavior! (I assume
it is implementation-defined when you memcpy() between objects of
different types.) In other words, the standard would have to say,
"Here are some undefined constructs, and here is the standard way for
writing them more concisely." There is nothing contradictory in this,
but you must admit it is a somewhat odd thing to say in a standard.
- Pat