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/12/2003 14:32:55
[ On Saturday, July 12, 2003 at 07:32:18 (-0400), der Mouse wrote: ]
> Subject: Re: toolchain/22118: make won't compile with -Wcast-qual -Wstrict-prototypes and more
>
> Who says any function is involved?

the subject line of this thread....  :-)

> Many of the times I want deconsting are
> for assignments, typically to structs that are part of externally
> defined interfaces (obviously, not designed for const-poisoned use).

Indeed this is also a potential headache for const, especially when you
add "-Wwrite-strings" to the list of warnings.

Here's an example of what I do when I want to allow GCC to be pedantic
about const with -Wwrite-strings:

	#include <sys/types.h>
	#include <limits.h>
	#include <db.h>
	#include <fcntl.h>

	#define MAGIC	"a magic read-only string used as a db key"

        char *magic = safe_strdup(MAGIC);	/* discard const from string */

	[[....]]

        key.data = magic;
        key.size = sizeof(MAGIC);
        if ((db->get)(db, &key, &data, 0) == -1)
                value = DEFAULT_MAGIC;
        else
                memmove(&value, data.data, sizeof(value));
        free(magic);

Copying const qualified storage to non-const qualified storage is the
only safe and truly portable way you can discard const.  Everything else
is just a trick to destroy the attempts made by the compiler to ensure
the programmer doesn't do what he said he wouldn't do.  I.e. the
"-Wwrite-strings" warning should really always be turned on with
"-Wcast-qual" (at least when -fwritable-strings is not used) since they
are logically one in the same -- it's just that so many programmers are
not accustomed to making sure they always copy const-qualified storage
such as read-only string constants when they pass a pointer to it into a
function which might try to write to the read-only string constant.

Maybe const-pedantic compilers could be fixed to allow constant strings,
such as those used in initializers, to be declared as writable such that
their otherwise implied const qualifier wouldn't have to be discarded in
the first place (and such that the whole module doesn't have to be
compiled using "-fwritable-strings").  Since a "volatile" and "const"
make no real sense togethr in a cast maybe this could be done with the
existing "volatile" keyword in a cast:

        char *magic = (volatile char *) MAGIC;

        key.data = magic;

Or maybe it could be done with a special suffix character on a string
constant, such as a trailing 'W':

	#define MAGIC	"a magic read-only string used as a db key"W

	char *magic = MAGIC;

	key.data = magic;

-- 
								Greg A. Woods

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