Arthur J. O'Dwyer said:
Simon Biber writes:
Yes. A string literal is defined as a null-terminated,
non-modifyable but non-const array of char.
Nope, it ain't. [...]
If a string literal were an array *in any context*, it couldn't be used
as an array initialiser, because arrays cannot be used as array
initialisers.
Sure they can. Lvalues of type "array of type" are converted to
non-lvalue expressions of type "pointer to type"; except when they
are string literals used to initialize character arrays, or in some
other cases. This directly implies that string literals used to
initialize character arrays *are* lvalues of type "array of type", but
are *not* converted to expressions of type "pointer to type".
This is nothing more than a very contorted way of patching a bug
occurring elsewhere in the standard. Without that bug, all this silliness
would not have been necessary in the first place.
That may be. Still, I don't see anything wrong with the patch.
How can I take the address of these lvalues, BTW?
Duh.
char (*bar)[4];
bar = &"foo";
works for me.
I can't see "foo" being used as an initialiser for a character array.
So, this is certainly not the answer to my question.
Apparently so. It's a null-terminated array of char, which is what
most C programmers call a "string."
By this logic, "abc\0def\0ghi" and "abc" are the same string literal.
The C standard itself claims otherwise:
65) A character string literal need not be a string (see 7.1.1),
because a null character may be embedded in it by a \0
escape sequence.
How about char a[2] = "ab"; ?
That's a variable definition and initialization, not an object.
There are *two* objects referenced by that definition; the variable
'a', which has type char[2], and the string literal "ab", which has
type char[3] but might decay into something else - who knows? - but
not into a "pointer to char", because the Standard says so.
It is precisely this "object" that I was talking about. How can I
initialise an object of type char[2] with an object of type char[3]?
object, I must be
Then, how come the following code is legal:
char array[] = "abcde";
array[0] = 'A';
The integer constant 42 is non-modifiable. Then how come
the following code is legal:
int boo = 42;
boo = 1;
Take it up with Fortran.
Bad analogy. Where does the ``object'' "abcde" reside? Inside array!
They are not const-qualified.
Then, how come the following code is illegal:
const char array[] = "abcde";
array[0] = 'A';
Objects declared non-const are not const-qualified.
Then, how come the following code is illegal:
int boo = 42;
const int bar = boo;
bar = 1;
Another bad analogy. For the same reason.
Chapter and verse, please.
How do I get the address of such an array of characters? How can a
program check the existence of such an array of characters? I mean, of
course, one that it used as initialiser for an array of char.
The only possible answer would be that it resides inside the array being
initialised. But this leads to the above mentioned "paradoxes".
...never mind.
Life is what you make it.
In an ideal world, maybe. In the real one, there are plenty of things
beyond your control. Some of them, not particularly pleasant.
I don't see any "patch." I see contorted wording, probably
driven by the need to give everything a type, but it looks
like perfectly consistent and reasonable wording to me.
Feel free to call the patch "contorted wording". There is no need to
give every syntactical element of the language a type. What is the type
of the {1, "foo", 3.0} initialiser?
With a proper definition of the string literal semantics, there would be
no need for such "contorted wording".
Dan