Subject: Re: toolchain/22118: make won't compile with -Wcast-qual -Wstrict-prototypes and more
To: NetBSD Toolchain Technical Discussion List <tech-toolchain@NetBSD.org>
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
List: tech-toolchain
Date: 07/15/2003 13:18:38
> In a parameter declaration [const] does mean what you said in that
> other message:  "data is not changed through this access path."
> However in a string constant, and thus a pointer initialized to point
> at the storage holding a string constant, it means somewhat the
> opposite:  "the area this pointer points to might be read-only and
> this pointer must always be passed in parameters declared as pointing
> to const storage, or be assigned to other variables similarly
> const-qualified."

That's not quite right.  String constants' data always "might be
read-only".  Telling gcc to make them array of const char rather than
array of char (which, IIRC, is itself nonstandard) is simply a way to
help the coder detect, at compile-time, some types of code that can
lead to attempts to write into one of them.  You are trying to conflate
the readonlyness of string constants' data (which leads to a "this
storage must never be written to" dictum) with gcc's -Wwrite-strings
option to make them arrays of const char, decaying to pointers to const
char, in which the const qualifier means exactly and only what it means
for any other pointer to const char.  String constants are still
read-only if you don't use -Wwrite-strings.

> const-qualified storage can never be portably de-const-ified,

No.  But pointer-to-const can be portably converted to
pointer-to-nonconst.  (What cannot be portably done is to write through
the resulting pointer, unless it came from a pointer-to-nonconst in the
first place.)

> If your API requires string constants to be writable ...

You appear to be confusing "writable string constant" with "non-const
pointer to string constant".  Generating the latter (eg, with my
deconst()) does not produce the former; it appears that you think I
think it does.  If so, you are wrong; I know it doesn't, and that's not
what I'm trying to achieve by using deconst().

There are plenty of APIs that call for non-const pointers but
nevertheless do not try to write into the storage pointed to.
(writev() is an example.)  _They_ are what I use deconst() for.

> (i.e. if you ever have to pass a pointer to free() then the parameter
> you acquire that pointer from must not be qualified as pointing to
> const storage, even if you don't always pass that pointer to free()
> ...)

Why not?  Where is the nonportability in stripping the const and
calling free() when the const-qualified pointer was obtained by adding
const to a pointer obtained from malloc() in the first place?

>> 1) Make the element pointer-to-const, and deconst it when freeing;
>> 2) Make the element pointer-to-nonconst, and deconst it when assigning;
>> 3) Don't use string literals even for the root;
>> 4) Duplicate the struct definition, [with and without const];
>> 5) Disable or ignore the warnings [...].
> Given the current definition of Standard C, (3) and (4) are the only
> correct and portable solutions,

You keep claiming this, but you never back it up.  Please cite chapter
and verse explaining how my deconst() violates the standard.  (Not,
note, using deconst() *and then writing through the result*.)

/~\ The ASCII				der Mouse
\ / Ribbon Campaign
 X  Against HTML	       mouse@rodents.montreal.qc.ca
/ \ Email!	     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B