Subject: Re: toolchain/22118: make won't compile with -Wcast-qual -Wstrict-prototypes and more
To: der Mouse <mouse@Rodents.Montreal.QC.CA>
From: Greg A. Woods <woods@weird.com>
List: tech-toolchain
Date: 07/14/2003 20:31:03
[ On Monday, July 14, 2003 at 19:00:40 (-0400), der Mouse wrote: ]
> Subject: Re: toolchain/22118: make won't compile with -Wcast-qual -Wstrict-prototypes and more
>
> > So, just as when [...], the only portable way to initialize a struct
> > iovec for writev() (without having GCC complain to you and without
> > using -fwritable-strings) is to allocate writable storage and copy
> > the string constants into it.
> 
> I disagree.
> 
> What's nonportable about this?

Well except for the possibility that a void* and a char* have different
internal representations the only a proper cast would cure there's
nothing terribly non-portable about it in the unix-like world.  Of
course you could make a specific char_ptr_deconst() function that
wouldn't suffer this problem....

However it doesn't work in general for the desired purpose and is thus
useless for all the examples that everyone else has proposed require
some DECONST() function/operator/whatever.

It's no better, and not much different, than relying on the GCC "bug" of
using "char foo[]"

I.e. you have not made the storage for your string constant writable and
yet you now have a non-const-qualified pointer to that read-only storage.

You've simply hidden your pointer aliasing from the compiler's checks
and thus made your attempts to use 'const' qualifiers in the first place
all null and void.  You may as well just use '-fwritable-strings' and be
done with it -- at least that way you avoid having to jump through all
the hoops you've put in your own way.

> It certainly "works", in that it it produces no warnings for me, with
> -Wcast-qual -Wwrite-strings.

The warnings are irrelevant if what you really end up doing is
accidentally trying to pass that artificially de-const'ed pointer to
free() or similar.  If you're sure you'll never do that then why bother
using 'const' in the first place (or you don't mind using run-time
errors to catch such bugs) -- i.e. just don't turn on -Wcast-qual and
none of the pesky 'const' qualifiers in standard APIs will bother you
with irrelevant warnings!

> > In C it is simply impossible to portably discard 'const' without
> > copying the data from read-only storage to writable storage.
> 
> What's nonportable about the above?

Your hack doesn't copy the string constant from read-only storage into
writable storage -- it simply aliases an unqualified pointer to the
read-only storage and thus allows you to break the compile-time rules
that the proper use of 'const' would otherwise enforce.

Remember "const char *" qualifies the storage being pointed to, not the
storage for the pointer itself.

> > 	char fooarray[] = "abc";
> 
> This is not an assignment; it is an initialization.

Yes, but that differentiation is not important here....

>  Arrays cannot be
> assigned.

Dimensionless arrays are really pointers, not arrays, and for an "auto"
variable the initialization is in fact implemented as an assignment.

Regardless "fooarray" is equivalent to a "char *" when it comes to
parameter passing and thus still points to read-only storage even though
it hasn't been qualified as pointing to read-only storage.  I.e. this is
just another pointer aliasing trick.  The compiler could catch it, but
doesn't for some reason or another.

-- 
						Greg A. Woods

+1 416 218-0098                  VE3TCP            RoboHack <woods@robohack.ca>
Planix, Inc. <woods@planix.com>          Secrets of the Weird <woods@weird.com>