jack@cwi.nl (Jack Jansen) (01/07/91)
The SGI C compiler treats the following two pointers as unequal: register volatile struct foo *p1; volatile register struct foo *p2; p1 is a pointer (in a register) to a volatile struct foo, while p2 is a volatile pointer (in a register) to a struct foo. Gcc treats the pointers as identical, and in my opinion this is as it should be. However, I haven't been able to find anything in the standard about the interaction of storage classes and type qualifiers. Since the 'register' in the declaration of p2 already refers to the variable p2 it is argueable that the volatile in front of it can't refer to the structure anymore. Could anyone who knows the standard better than I do please shed some light on this? (preferrably by mail, I don't read this group too often. I'll summarize) -- -- Een volk dat voor tirannen zwicht | Oral: Jack Jansen zal meer dan lijf en goed verliezen | Internet: jack@cwi.nl dan dooft het licht | Uucp: hp4nl!cwi.nl!jack
henry@zoo.toronto.edu (Henry Spencer) (01/08/91)
In article <2760@charon.cwi.nl> jack@cwi.nl (Jack Jansen) writes: >The SGI C compiler treats the following two pointers as unequal: > register volatile struct foo *p1; > volatile register struct foo *p2; >p1 is a pointer (in a register) to a volatile struct foo, while >p2 is a volatile pointer (in a register) to a struct foo. This is incorrect. The standard attributes no significance to the order of storage class specifiers, type specifiers, and type qualifiers in the declaration-specifiers list beginning a declaration. The type specifiers (in this case `struct foo') and type qualifiers (`volatile') all go to forming the "base type", so to speak, for the declaration. The way to declare a volatile pointer (in a register) to a struct foo is register struct foo * volatile p3; See the pointer-declarator rules in 3.5.4.1. >... I haven't been able to find anything in >the standard about the interaction of storage classes and type >qualifiers. That's because there is none. The storage class is completely independent of the type. -- If the Space Shuttle was the answer, | Henry Spencer at U of Toronto Zoology what was the question? | henry@zoo.toronto.edu utzoo!henry
diamond@jit345.swstokyo.dec.com (Norman Diamond) (01/08/91)
In article <2760@charon.cwi.nl> jack@cwi.nl (Jack Jansen) writes: >The SGI C compiler treats the following two pointers as unequal: > register volatile struct foo *p1; > volatile register struct foo *p2; >p1 is a pointer (in a register) to a volatile struct foo, while >p2 is a volatile pointer (in a register) to a struct foo. > >Gcc treats the pointers as identical, and in my opinion this is >as it should be. However, I haven't been able to find anything in >the standard about the interaction of storage classes and type >qualifiers. Since the 'register' in the declaration of p2 already >refers to the variable p2 it is argueable that the volatile in front >of it can't refer to the structure anymore. Interesting. I thought this would be well defined in the standard (i.e. that p2 has to be the same as p1) but it isn't. Section 3.5 includes the following excerpts (except for line numbers): (1) declaration: (2) declaration-specifiers init-declarator-list/opt (3) declaration-specifiers: (4) storage-class-specifier declaration-specifiers/opt (5) type-specifier declaration-specifiers/opt (6) type-qualifier declaration-specifiers/opt (7) init-declarator-list: (8) init-declarator (9) init-declarator-list , init-declarator (10) init-declarator: (11) declarator (12) declarator = initializer The declaration specifiers (line 3) consist of a sequence of specifiers that indicate the linkage (line 4), storage duration (line 4), and part of the type of the entities (lines 5, 6) that the declarators (line 11) denote. Section 3.5.4 tells what kinds of entities declarators can denote: (13) declarator: (14) pointer/opt direct-declarator (15) direct-declarator: (16) identifier (17) ( declarator ) (18) direct-declarator [ constant-expression/opt ] (19) direct-declarator ( parameter-type-list ) (20) direct-declarator ( identifier-list/opt ) (21) pointer: (22) * type-qualifier-list/opt (23) * type-qualifier-list/opt pointer Section 3.5.3 "constrains" the qualifiers: The same type qualifier shall not appear more than once in the same specifier list (line 3?) or qualifier list (lines 22, 23?), either directly or via one or more typedefs. (Section 3.5.3 does not contain a forward reference to section 3.5.4, but both of these references are the best interpretations that I can guess.) At least, it seems that "register const" and "const register" both refer to the same entity. Which entity it is, we will determine in a moment. Nonetheless, either p1 and p2 are the same, or else *p1 and *p2 are the same. SGI seems to be broken. Now, what about GCC? OK, so what does section 3.5 say about: register const int *a; register, const, and int all describe *a, because *a is the entity denoted by line 11. Hmm, section 3.5 seems to be in trouble. No one, but no one, obeys section 3.5 with regard to "register". Everyone, but everyone, obeys section 3.5 with regard to "int". Everyone THOUGHT that it should be disobeyed with respect to "const". But SGI accidentally obeys it sometimes, while disobeying it other times. GCC never obeys it. OK, let's pretend that section 3.5 says "identifier" (fixed up somehow) instead of "declarator". (Mr. Gwyn will doubtless assert that it already says that.) Now, what does it say about: register const int *a; register, const, and int all describe a? Everyone obeys this with regard to "register". No one obeys this with regard to "int". Everyone thought that this should be obeyed with regard to "const". Again, SGI is inconsistent. GCC always obeys it. Section 3.5 needs to be fixed. SGI needs to be fixed. I predict that, if section 3.5 is fixed, GCC's behavior will be correct. -- Norman Diamond diamond@tkov50.enet.dec.com If this were the company's opinion, I wouldn't be allowed to post it.
davea@quasar.wpd.sgi.com (David B.Anderson) (01/09/91)
In article <1991Jan8.000756.24432@zoo.toronto.edu> henry@zoo.toronto.edu (Henry Spencer) writes: >In article <2760@charon.cwi.nl> jack@cwi.nl (Jack Jansen) writes: >>The SGI C compiler treats the following two pointers as unequal: Henry's corrections are appropriate. What started this is a compiler bug that caused rejection of a legal assignment. By e-mail, Jack Jensen sent me a complete example: volatile struct foo { int y; } *ptr; main() { register volatile struct foo *p1; volatile register struct foo *p2; /* compiler gets ``wrong struct'' */ p1 = ptr; p2 = ptr; /* compiler rejects this: compiler bug */ } ccom: Warning: tv2.c, line 11: illegal structure pointer combination p2 = ptr; ------------^ CHARACTERIZATION: Considering: X to be volatile, const, int, char, unsigned, struct foo (etc) or a combination and Y to be register, auto, extern, static, typedef then X Y X would not always get the compiler-internal Node data correct. the type would be right, but other data (like the structure index) would come from the first X only and ignore the second. WORKAROUND: Using Y X instead is recommended practice and works around the bug. FIX: This previously unknown bug will be fixed (today) for the next major release (4.0). Thanks to Jack Jensen for letting us know about the problem. Sorry for any inconvenience this may have caused.... [ David B. Anderson Silicon Graphics (415)335-1548 davea@sgi.com ] [``What can go wrong?'' --Calvin to Hobbes]
thorinn@diku.dk (Lars Henrik Mathiesen) (01/09/91)
diamond@jit345.swstokyo.dec.com (Norman Diamond) writes: (ND>)
In article <2760@charon.cwi.nl> jack@cwi.nl (Jack Jansen) writes: (JJ>)
JJ>The SGI C compiler treats the following two pointers as unequal:
JJ> register volatile struct foo *p1;
JJ> volatile register struct foo *p2;
JJ>p1 is a pointer (in a register) to a volatile struct foo, while
JJ>p2 is a volatile pointer (in a register) to a struct foo.
JJ>
JJ>Gcc treats the pointers as identical, and in my opinion this is
JJ>as it should be. However, I haven't been able to find anything in
JJ>the standard about the interaction of storage classes and type
JJ>qualifiers. Since the 'register' in the declaration of p2 already
JJ>refers to the variable p2 it is argueable that the volatile in front
JJ>of it can't refer to the structure anymore.
I read this to mean that GCC took both declarations as "register
pointer to volatile struct foo" (as it should). Below, you seem to
think that GCC made the pointer volatile.
ND>Interesting. I thought this would be well defined in the standard
ND>(i.e. that p2 has to be the same as p1) but it isn't.
ND>Section 3.5 includes the following excerpts (except for line numbers):
ND> [grammar rules deleted, and references to them below]
ND> The declaration specifiers consist of a sequence of specifiers
ND> that indicate the linkage, storage duration, and part
ND> of the type of the entities that the declarators
ND> denote.
I think the problem is the wording "the entities that the declarators
denote". A priori, it might well mean what you seem to assume
(something like "operands of the same form as the declarators", see
the formulation in 3.5.4 Semantics). It might also mean "the
identifiers declared by the declarators"; as I'll argue below, and
knowing what was intended, that's probably the best interpretation.
Note that it says "part of the type" --- if the first meaning was
intended, the type-specifiers and type-qualifiers here would give the
precise type of the "entity", not just part.
ND>At least, it seems that "register const" and "const register" both refer
ND>to the same entity. Which entity it is, we will determine in a moment.
ND>Nonetheless, either p1 and p2 are the same, or else *p1 and *p2 are the
ND>same. SGI seems to be broken. Now, what about GCC?
I'll just comment on the results you get when you make the same
assumption as I do.
ND>OK, let's pretend that section 3.5 says "identifier" (fixed up somehow)
ND>instead of "declarator". (Mr. Gwyn will doubtless assert that it already
ND>says that.)
ND>Now, what does it say about:
ND> register const int *a;
ND>register, const, and int all describe a?
ND>Everyone obeys this with regard to "register".
Yes.
ND>No one obeys this with regard to "int".
I think they do, because here's where the "part of the type" comes in.
If you read the explanation in 3.5.4 Semantics, and then read 3.5.4.1
(Pointer declarators), you'll see that the type of a in "int *a" is
determined like this:
"int *a" has the form "T D1", where T == "int" and D1 == "* a"
So D1 has the form "* D", where D == "a"
In the declaration T D, that is "int a", the type specified for a is
integer.
Therefore, the type specified for a in "int *a" is pointer to integer.
So integer really is part of the type of the identifier declared.
ND>Everyone thought that this should be obeyed with regard to "const".
ND>Again, SGI is inconsistent.
ND>GCC always obeys it.
I think you got this backwards, perhaps. "const int *a" declares a
pointer to a readonly integer, and that's what GCC takes it to do. In
your terms, that would be disobeying this interpretation of 3.5,
wouldn't it?
ND>Section 3.5 needs to be fixed. SGI needs to be fixed. I predict that,
ND>if section 3.5 is fixed, GCC's behavior will be correct.
Section 3.5 could certainly do with a better wording, but once you
know what's intended, it's not wrong. SGI is wrong.
--
Lars Mathiesen, DIKU, U of Copenhagen, Denmark [uunet!]mcsun!diku!thorinn
Institute of Datalogy -- we're scientists, not engineers. thorinn@diku.dk
gwyn@smoke.brl.mil (Doug Gwyn) (01/09/91)
In article <1991Jan8.011724.25209@jituha.enet.dec.com> diamond@tkov50.enet.dec.com (Norman Diamond) writes: >OK, let's pretend that section 3.5 says "identifier" (fixed up somehow) >instead of "declarator". No, there is nothing wrong with the wording of 3.5 that I can see. SGI apparently simply got the implementation wrong; there are numerous problems in their ANSI C support as of Irix release 3.3. We'll see if it is fixed in their forthcoming new C implementation.