Subject: Re: toolchain/22118: make won't compile with -Wcast-qual
To: NetBSD Toolchain Technical Discussion List <tech-toolchain@NetBSD.org>
From: Greywolf <greywolf@starwolf.com>
List: tech-toolchain
Date: 07/18/2003 14:30:56
Thus spake Greg A. Woods ("GAW> ") sometime Today...
GAW> I have never said any such thing. What I do want, and with GCC what I
GAW> do have, is an implementation of Standard C which gives me the ability
GAW> to know at compile time whether or not my code could potentially suffer
GAW> a bug that might result in an attempt to modify a constant.
Unfortunately (or fortunately, depending on your POV), GCC != "Standard C",
at least not strictly speaking, unless you count extensions to the standard
as part of the standard.
GAW> "const" would not have been necessary if the ANSI committee had done
GAW> their job properly and standardized the original C language instead of
GAW> inventing a new variant language. (K&R, 1st edition, Appendix A, 2.5
GAW> (p.181): "All strings, even when written identically, are distinct.")
[which is something that I think xstr managed to circumvent, thank
goodness, thus allowing one to reduce the amount of space used by
liberally sprinkled identical string constants.]
GAW> Hmmm -- yes, such as, for example, Smalltalk-80 or even Common LISP.
LISP is much more entertaining (at least from a certain POV (or so it
might (possibly) seem)) when applied to a spoken language (such as
(for example) English) :).
GAW> I am most certainly not trying to describe an ideal language -- as C is
GAW> anything but. I am discussing the situation in the real-world for C
GAW> code that attempts to be portable regardless of whether the target
GAW> implementations it is to be compiled with are themselves strictly
GAW> compliant with the C Standard or not.
Off topic a bit:
Hm. C is anything but an ideal language. I'm sure a lot of folks out
there might agree with that, but I fail to see precisely why. The points
I've heard against it are by and large:
- lack of object-orientation, and
- the ease by which bad code is able to be written.
To address the first one, I see that it might be a problem, but rarely.
I just don't see OO as a huge plus -- it usually generates much more
bloated code on output.
To address the second one, well, Hell's bells, people, if you have a sharp
sword (and C is still sharper than most (no pun intended)), you're
occasionally going to lose control of the blade and cut yourself once in a
while.
GAW> That very first point I tried to make was primarily that any attempt to
GAW> invent a DECONST() macro/function/cast/whatever was clearly and
GAW> blatantly wrong on all counts and secondarliy that the very attempt to
GAW> justify such a construct always relies only on some earlier mistake
GAW> caused by either trying to add a "const" qualifier to a parameter where
GAW> it did not belong or else making the mistake of assuming that string
GAW> literal constants were not at least implicitly "const"-qualified.
GAW>
GAW> I.e. if you think you need DECONST() then you are mistaken as the real
GAW> problem is elsewhere. So far nobody has demonstrated even a hint of a
GAW> standard (de facto or otherwise) API which mis-uses "const" and thus
GAW> would require DECONST() tricks to either implement or use it without
GAW> changing the original API (minutely, and in an ABI-compatible fashion).
I would say, then, that most places const is used it oughtn't be, such as
common areas intended to be potentially both written and read. If you
The Programmer *really* do not intend for the storage path to be modified,
fine, use const. Otherwise, leave it out.
GAW> I'm also very happy to learn from this discussion that GCC's use of
GAW> writable storage for "char foo[]" initializers is likely to be mirrored
GAW> by other conforming Standard C implementations. Up until now this was
GAW> something I had assumed was a GCC specific behaviour and would may not
GAW> be copied by a strictly conforming implementation.
GAW>
GAW> (I suppose I also get somewhat worked up over this kind of issue because
GAW> of the fact that it would have been avoided in the first place if ANSI C
GAW> had not invented new and strictly unnecessary constructs such as shared
GAW> storage for string literals. Grrr. :-)
I think, more appropriately, it would seem that they were only trying to
establish a standard by permitting string literals to be written to.
[NOTE: went back and re-read what you meant regarding shared storage, and
I get it (shared storage does not necessarily denote RO or RW). I agree
with this viewpoint; even xstr didn't allow shared storage -- it provided
a reference into the storage with an index into an array of pointers.
But I digress...]
Such behaviour, as I understand it, was never guaranteed to be allowed;
the fact that it Just Worked under, i.e. 4.2BSD on the VAX, for example,
was fortuitous, IIRC. There were warnings sprinkled all over the place
-- especially in various newsgroups (comp.lang.c) -- which stated that
writable initialised data was not a guarantee; in fact, I seem to remember
one implementation which did not allow things in the .data section to be
explicitly modified -- one had to copy them out of the initialised variable
into dynamic storage in order to use them.
Damned if I can remember which implementation that was, but I'm glad to be
rid of it.
Just for the record, I threw this together and compiled with Sun's
(unbundled) cc as well as gcc, and here's what I discovered from the
resulting .s files, near's I can tell:
/* start */
/* GCC */
char textbar[]="Text?"; /* BOTH: .data [RW] */
char textbar2[14] = "Is this text?"; /* BOTH: .data [RW] */
char *textptr="Textpointer?"; /* GCC: .rodata, Sun: .data1 [RW] */
int unalloc; /* GCC: .text, Sun: .data */
int alloc=2; /* BOTH: .data */
char *text(argc, argv)
int argc;
char *argv[];
{
char *textest = "is this in .text?"; /* G: .rodata, S: .data1 [RW] */
char textest2[] = "How about this?"; /* BOTH: .rodata */
char textest3[9] = "Or this?"; /* BOTH: .rodata */
int ialloc = 4;
int iunalloc;
union {
char u_c;
short u_s;
long u_l;
double u_align;
} c[1];
}
/* end */
I find it interesting, the different treatment of char * by the two
compilers...
--*greywolf;
--
NetBSD: the second best thing you can get for free.