Subject: Re: toolchain/22118: make won't compile with -Wcast-qual
To: None <tech-toolchain@NetBSD.org>
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
List: tech-toolchain
Date: 07/18/2003 19:22:27
>>> int unalloc;    /* GCC: .text, Sun: .data */
>> .text?  Not .bss?  Are you sure?
> Yes.  There is no .bss segment produced, in fact; it might be
> considered .common, I don't know, but in any case "unalloc" did not
> show up there.

> Since 'unalloc' is outside the scope of a function, and lives in the
> global section, quite honestly, I'm very surprised that SunPRO-C put
> it in .data!  Only in-function unallocated data goes in .bss, to my
> knowledge.

If the compiler uses a def/ref model, I'd expect it to go in .data; if
the compiler uses a common model, I'd expect it to be .common, ending
up in .bss if no module has an initialized definition.  But .text??
That makes no sense whatever to me.  Can you quote the relevant lines
from the .s file?

> Yes, probably, but keep in mind that if you don't want the pointer
> variable to change, you must use "char const *var";

"char * const var".

"char const * var" is semantically identical to "const char * var": a
non-const pointer to const char.  "char * const var" is a const pointer
to non-const char; "const char * const var" (or "char const * const
var") gives a const pointer to const char.

Yes, this can be confusing.

>     char *writeme = "where is this?";	/* S: .data1, G: .rodata */
>     const char *can_i = "write this?";	/* BOTH: .rodata */

Now _that_ surprises me.  Sun is propagating the constness of the
pointed-to chars through to the initializer, affecting the decision as
to whether to make the string's chars read-only or not.

> char *writeme = "writeme";
> 	/* Sun: writeme: .data [RW], *writeme: .data1 [RW] */
> 	/* GCC: writeme: .data [RW], *writeme: .rodata [RO] */
> const char *can_i = "can I?";
> 	/* Sun: can_i: .data [RW], *can_i: .rodata1 [RO] */
> 	/* GCC: can_i: .data [RW], *can_i: .rodata [RO] */
> char * const doubt_it = "Nope.";
> 	/* Sun: doubt_it: .rodata [RO], *doubt_it: .data1 [RW] */
> 	/* GCC: doubt_it: .rodata [RO], *doubt_it: .rodata [RO] */

In view of the above, these do not surprise me.  Const pointer
variables go RO; string constants behave as above: always RO for gcc,
RO or RW for Sun depending on whether declared const.

> I find it interesting that Sun will separate the constance of a
> pointer from the constance of what it points to, while GCC lumps them
> together, saying that if you can't modify the pointer, you also
> cannot modify where it points, which, semantically, I disagree with.

Me too - but I think in gcc's case it's not so much "const char *" vs
"char *" as it is that string literal text is always RO.  Note that gcc
put the string literal data in .rodata even for `writeme'.

You could try `const char * const never = "Never!";' as well; I expect
it to be

	Sun: never: .rodata, *never: .rodata1
	gcc: never: .rodata, *never: .rodata

/~\ 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