[comp.std.c] const in latest draft

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.