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/16/2003 14:25:49
[ On Wednesday, July 16, 2003 at 02:47:08 (-0400), der Mouse wrote: ]
> Subject: Re: toolchain/22118: make won't compile with -Wcast-qual -Wstrict-prototypes and more
>
> >> Using `char foo[] = "string"' does de-const the string.
> 
> Not really; it was never const to begin with, because the double-quoted
> text is not a string constant in the usual sense; it is an initializer,
> an abbreviation for { 's', 't', 'r', 'i', 'n', 'g', '\0' } (modulo the
> removal of the trailing '\0' if the string's length exactly matches the
> declared size of the array).

I beg to differ, as do Harbison and Steele, page 30, section 2.7.4.

Even K&R 2nd Ed. seems to disagree with you if you read carefully and
keep everything in context.

> I believe your informal sources are wrong.  Second Edition K&R says
> (A8.7)
> 
> 	As a special case, a character array may be initialized by a
> 	string literal; successive characters of the string initialize
> 	successive members of the array.  [...]  If the array has
> 	unknown size, the number of characters in the string, including
> 	the terminating null character, determines its size; if the
> 	size is fixed, the number of characters in the string, not
> 	counting the terminating null character, must not exceed the
> 	size of the array.

First off note that K&R, even the second edition, is also an "informal
source".

Secondly I read nothing in the above which implies in any way that the
storage for the string constant used as an array initializer cannot ever
be read-only.  Indeed the other quote you made of K&R confirms that
string constants may be read-only.

I suppose we still need to ask someone with a copy of the final ISO C
standard, but I'm reasonably confident that GCC is allowing non-portable
code to bypass 'const' warning when it de-const-ifies string constants
used as array initializers.

Note also that there is no distinction in Standard C (though there seems
to be in GCC's implementation) between a definition in the form "char
foo[]" and a definition in the form "char *foo".  Both forms define a
pointer to a char.  An array name is merely treated as a pointer to the
first element of the array (especially in the context of being a
function parameter, the case most important for this thread).  No
separate storage is allocated when an array is given no size but rather
just a string-constant as an initializer.  When that initializer is a
string constant then the storage for the array is const-qualified since
the string constant may be read-only and if the compiler does implement
read-only string-constants then it _MUST_ warn that the implied "const"
qualifier is being ignored in the initialization statement.  Also two
separate char array variables which are initialized with an identical
string constant _may_ point to the same storage address.

> Note in particular that a string's type does not involve const; that is
> a gccism, occuring only in the presence of -Wwrite-strings.

Again, I beg to differ.  All sources I've found are quite explicit in
saying that an implementation _MAY_ use read-only storage for string
constants and as such they must _always_ be const-qualified.  Indeed the
last sentence of the second quote you copied from K&R only confirms what
I say (A2.6):

	Whether identical string literals are distinct is
	implementation-defined, and the behavior of a program that
	attempts to alter a string literal is undefined.

-- 
						Greg A. Woods

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