J
Jack Klein
Ark said:Richard Heathfield wrote: [...]The behaviour resulting from modifying a constant string is
undefined. A segmentation fault is one possible result. The absence
of a segmentation fault is another possible result. And the
destruction of Rome by fire is another possible result.
It would be clearer to use the term "string literal" rather than
"constant string".
I am confused profoundly.
I always thought that where the string literals are stored (RO vs. RW)
is implementation-defined
Yes.
(and decent compilers would allow me to
choose my way with a command-line switch).
That's debatable. I don't see much advantage in allowing string
literals to be modifiable (except *maybe* to handle old and broken
code).
However, the /type/ of (a pointer to) a string literal is char *,
regardless of the switch, or so I read the standard a while ago.
Yes.
So the statement
*a='a';
must compile OK *without diagnostics* and then cause or not cause
undefined behavior depending on implementation-defined behavior.
The following:
char *a = "hello";
*a = 'a';
(assuming it appears in an appropriate context) is legal (it violates
no syntax rules or constraints), and a conforming compiler must accept
it. But, as always, a compiler is free to issue any diagnostics it
likes. The standard requires diagnostics in certain cases; it never
forbids them.
No, a conforming compiler is not required to accept it, although I
don't know of any that will not. If the compiler can determine, at
compile time, that a statement or expression producing undefined
behavior will be executed by all possible paths through the program,
it is free to do anything at all at compile time.
For example:
#include <stdlib.h>
#include <time.h>
int main(void)
{
char *a = "I'm a string literal";
srand(time(0));
if (rand() > (RAND_MAX / 2))
{
*a = 'a';
}
return 0;
}
A compiler must translate the program above.
However:
int main(void)
{
char *a = "I'm a string literal";
*a = 'a';
return 0;
}
....a compiler is not required to translate the second form.
The really interesting question is if the call to srand() is omitted
from the first example. Is a compiler allowed to "know" that its
version of rand() will return a value greater than RAND_MAX / 2 with
default initialization, equivalent to srand(1)?
^^^^^^^^^^^^^^If the initialization is executed, it invokes undefined behavior. The
ITYM assignment.