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>