sarima@gryphon.COM (Stan Friesen) (05/30/89)
I have a few questions about the latest draft of the ANSI standard regarding the treatment of the const qualifier. I have the Jan. 11, 1988 version of the draft standard and would like to know if there have been any substantive changes in the rules regarding type qualifiers since then, other than dropping the noalias qualifier. In particular, I would like to know if the clause in 3.5.3 stating that "For two qualified types to be compatible, both shall have the identically qualified version of a compatible type" is still present? Also, is the footnote on the previous page stating "The implementation may place a const object that is not volatile in read-only storage" still present? I presume that it is still true that "All declarations that refer to the same object or function shall have compatible type; otherwise the behavior is undefined" (as per 3.1.2.6). I am asking because I question the necessity of an implementation decision made by Lattice Corp in version 3.4 of their C compiler, and I need to know if my reasoning based on the Jan 11 draft is still valid. -- Sarima Cardolandion sarima@gryphon.CTS.COM aka Stanley Friesen rutgers!marque!gryphon!sarima Sherman Oaks, CA
gwyn@smoke.BRL.MIL (Doug Gwyn) (05/30/89)
In article <16259@gryphon.COM> sarima@gryphon.COM (Stan Friesen) writes: >[is] the clause in 3.5.3 stating that "For two qualified types to be >compatible, both shall have the identically qualified version of a >compatible type" ... still present? Yes. >is the footnote on the previous page stating "The implementation may place >a const object that is not volatile in read-only storage" still present? Yes. >[is it] still true that "All declarations that refer to the same object or >function shall have compatible type; otherwise the behavior is undefined" >(as per 3.1.2.6) [?] Yes. >I am asking because I question the necessity of an implementation decision >made by Lattice Corp in version 3.4 of their C compiler, and I need to know >if my reasoning based on the Jan 11 draft is still valid. I don't know what Lattice has been up to; if you would tell us then perhaps we could directly address the specific issue. Note that the final draft clarifies that qualified and unqualified versions of a type have the same representation and alignment requirements, as do pointers to qualified and unqualified versions of compatible types. This implies interchangeability as arguments to functions, return values from functions, and members of unions, thus legitimatizing a decision K&R made when preparing examples for the second edition of their book.
henry@utzoo.uucp (Henry Spencer) (05/31/89)
In article <16259@gryphon.COM> sarima@gryphon.COM (Stan Friesen) writes: >... I have the Jan. 11, 1988 >version of the draft standard and would like to know if there have been any >substantive changes in the rules regarding type qualifiers since then, other >than dropping the noalias qualifier. In a word, yes. I don't even remember what the Jan 88 draft said, but it is almost certainly badly out of date by now. The qualifier situation was a mess, and has been cleaned up considerably. > In particular, I would like to know if the clause in 3.5.3 stating >that "For two qualified types to be compatible, both shall have the identically >qualified version of a compatible type" is still present? Yes. >...is the >footnote on the previous page stating "The implementation may place a const >object that is not volatile in read-only storage" still present? Yes. >I presume >that it is still true that "All declarations that refer to the same object >or function shall have compatible type; otherwise the behavior is undefined" >(as per 3.1.2.6). Yes. -- Van Allen, adj: pertaining to | Henry Spencer at U of Toronto Zoology deadly hazards to spaceflight. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
pardo@june.cs.washington.edu (David Keppel) (06/01/89)
In article <16259@gryphon.COM> sarima@gryphon.COM (Stan Friesen) writes: >[Discussion of `const' qualifier] I posted a related question about this a while back. I kept the e-mail that I exchanged, in the hope that it would make sense eventually. I've sat on this for a while and I'm still not sure that I understand. Here goes again: I declare a function parameter such as is used by qsort. Unlike qsort, I don't in general require that the function have no side effects, but do want to be able to pass functions that don't have side effects. My understanding of the `const' qualifier is that, when applied to the object type of a pointer function parameter, the function guarantees that it will not change the storage being pointed to. int blah (void const *zork); Says that `blah' will not change whatever `zork' points to. I declare some functions. typedef int (*functype) (void *object); typedef int (*c_functype) (void const *const_object); void toplevel (functype); functype f1; c_functype f2; Calling the parameter functions directly works as expected. const void *object = POINTER_TO_VOID; const void *c_object = POINTER_TO_CONST_VOID; (*f1) (object); /* OK */ (*f2) (object); /* OK */ (*f1) (c_object); /* ERROR */ (*f2) (c_object); /* OK */ Basically, any place that `f1' appears in the code, I can replace it with a call to `f2'. Calling the parameter functions indirectly does not do what I expect. void toplevel (functype f) { (*f)(object); } : : toplevel (f1); /* OK */ toplevel (f2); /* ERROR */ I expect that when the second call will be OK, because I'm passing in a function that guarantees that it won't change its parameters. That function is being used to replace a function that might change its parameters, so the replacement won't do anything that the original couldn't do. Surely there's nothing wrong with that!? Still, I get a `argument passing between incompatible pointer types' type clash warning message from my friendly local dpANS-conformant compiler. According to a clip of the May '88 draft that somebody mailed me (Section 3.5.4.2): For two function types to be compatible, both shall specify compatible return types. Moreover, the parameter type lists, if both are present, shall agree in the number of parameters [...]; corresponding parameters shall have compatible types [...] For each parameter declared with qualified type, its type for these comparisons is the unqualified [Emph. mine] version of it's declared type. So what's my compiler doing? Is this a bug or a feature? Insight is appreciated. ;-D on ( Promotion rules? *Surfing* rules! ) Pardo -- pardo@cs.washington.edu {rutgers,cornell,ucsd,ubc-cs,tektronix}!uw-beaver!june!pardo
gwyn@smoke.BRL.MIL (Doug Gwyn) (06/01/89)
In article <8408@june.cs.washington.edu> pardo@cs.washington.edu (David Keppel) writes: > typedef int (*functype) (void *object); > typedef int (*c_functype) (void const *const_object); > c_functype f2; > const void *object = POINTER_TO_VOID; > void > toplevel (functype f) > { > (*f)(object); > } > toplevel (f2); /* ERROR */ The problem is that there is a requirement that the actual pointer argument in the function call be assignable to (an unqualified version of) the parameter type, and the constraints on simple assignment say that the type pointed to by the target of the assignment "has all the qualifiers of" the type pointed to by the pointer being assigned. "All" is apparently being interpreted as including nested inner qualifiers. I think that was actually the intention of this clause in the Standard, as a safety to catch possible obscure bugs in application use of qualified types. You can of course cast the argument to the appropriate type..
sarima@gryphon.COM (Stan Friesen) (06/04/89)
In article <1989May30.170530.336@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes: > >In a word, yes. I don't even remember what the Jan 88 draft said, but it >is almost certainly badly out of date by now. The qualifier situation was >a mess, and has been cleaned up considerably. > Absolutely, I don't doubt it. How can I *get* a copy of the final draft? Apparently it is not classified as a "public review" release, so the source I used to get the Jan 11 draft doesn't carry it. In fact they will not have anything past the Jan 11 draft until the standard is finally approved. Is there *any* way for us ordinary peons to get at the final draft? -- Sarima Cardolandion sarima@gryphon.CTS.COM aka Stanley Friesen rutgers!marque!gryphon!sarima Sherman Oaks, CA
sarima@gryphon.COM (Stan Friesen) (06/05/89)
In article <10339@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes: >In article <16259@gryphon.COM> sarima@gryphon.COM (Stan Friesen) writes: > >[Answers to my questions] >Yes. > >Yes. > >Yes. > Thank-you, I needed that. >>I am asking because I question the necessity of an implementation decision >>made by Lattice Corp in version 3.4 of their C compiler, and I need to know >>if my reasoning based on the Jan 11 draft is still valid. > >I don't know what Lattice has been up to; if you would tell us then perhaps >we could directly address the specific issue. > O.K. I wanted to double-check my reasoning before I stuck my foot in my mouth. It seems my reasoning should be valid, so here goes. In the User's Guide to Lattice 3.4, in section 5.3.5, it states: "ANSI has reserved 'const' to describe an object that never changes *within* *the* *module* that declares it as 'const',...". It then goes on to say: "Notice that a 'const' object, using the ANSI definition, is not necessarily unwritable. For example, suppose you define a global data object that only one function is supposed to change, while other functions need to read it. The object should be declared *without* the 'const' keyword in the former and *with* the 'const' keyword in the latter functions." [emphasis mine] From this they conclude that, to be ANSI compliant, they cannot place 'const' objects in a seperate, ROMable CONST section, but that they must be kept in the normal data section. They have thus introduced a new keyword, 'chip', for ROMable constants to be placed in the CONST section. On the basis of the material I quoted from the Jan 11 Draft Standard, I maintain this is *wrong*. It is *undefined* to declare the same variable both 'const' and non-'const', thus it is perfectly permissible for the compiler to break if one tries this. And it is certainly ANSI compliant to place 'const' objects in a ROMable section. Luckily this perverse behavior is option controlled, rather than unconditionally added. Needless to say, I will never use the compiler in the so-called ANSI mode with respect to 'const'. I would rather keep *real* ANSI compliance by placing 'const' stuff in a ROMable section. Lattice, are you out there and listening? -- Sarima Cardolandion sarima@gryphon.CTS.COM aka Stanley Friesen rutgers!marque!gryphon!sarima Sherman Oaks, CA
gwyn@smoke.BRL.MIL (Doug Gwyn) (06/05/89)
In article <16428@gryphon.COM> sarima@gryphon.COM (Stan Friesen) writes: > In the User's Guide to Lattice 3.4, in section 5.3.5, it states: >"ANSI has reserved 'const' to describe an object that never changes *within* >*the* *module* that declares it as 'const',...". I think the first problem is that this is an over-simplified description of what the semantics of the "const" type qualifier. Perhaps Lattice's interpretation was a consequence of the admittedly confusing specification for type qualifiers in earlier drafts of the standard. Certainly a non-volatile const object can be allocated to ROM.