The following program provokes systematic segmentation fault due to undefined behavior (trying to modify a string literal):
int main() {
char *s = "immutable";
s[0] = 'a';
return 0;
}
Still, there seems to be absolutely no way to tell GCC/Clang to emit even the slightest warning about it (-Wall -Wextra -pedantic -std=c11
don't do anything).
Especially for beginners, this kind of situation would be useful to inform about. Even for non-beginners, in some slightly less obvious situations it could be helpful:
void f(char *s) {
s[0] = '0';
}
int main() {
char *s = "immutable";
f("literal"); // oops
f(s); // oops
return 0;
}
Besides, this would help enforce some const
-culture in C programming.
Why are such cases deliberately ignored? Does the standard actively prohibit diagnostics from being emitted in such cases, or is it mostly for backwards-compatibility (trying to enforce them now would generate too many warnings)?
The warning is emitted only with --coverage enabled. By default, this warning is enabled and is treated as an error. -Wno-coverage-invalid-line-number can be used to disable the warning or -Wno-error=coverage-invalid-line-number can be used to disable the error. Suppress warning messages emitted by #warning directives.
gcc -Wall enables all compiler's warning messages. This option should always be used, in order to generate better code.
-Werror= Make the specified warning into an error. The specifier for a warning is appended, for example -Werror=switch turns the warnings controlled by -Wswitch into errors.
You can use a #pragma warning directive to control the level of warning that's reported at compile time in specific source files. Warning pragma directives in source code are unaffected by the /w option.
TL;DR C compilers do not warn, because they do not "see" a problem there. By definition, C string literals are null terminated char
arrays. It's only stated that,
[...] If the program attempts to modify such an array, the behavior is undefined.
So, in the compilation process, it is not known to the compiler that a char
array should behave as a string literal or string. Only the attempt to modification is prohibited.
Related read: For anybody interested, see Why are C string literals read-only?
That said, I am not very sure whether this is a good option, but gcc
has -Wwrite-strings
option.
Quoting the online manual,
-Wwrite-strings
When compiling C, give string constants the type
const char[length]
so that copying the address of one into a non-const char *
pointer produces a warning. These warnings help you find at compile time code that can try to write into a string constant, but only if you have been very careful about using const in declarations and prototypes. Otherwise, it is just a nuisance. This is why we did not make-Wall
request these warnings.
So, it produces a warning using the backdoor way.
By definition, C string literals (i.e., character string literals) are char
arrays with null terminator. The standard does not mandate them to be const
qualified.
Ref: C11
, chapter
In translation phase 7, a byte or code of value zero is appended to each multibyte character sequence that results from a string literal or literals. The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence. For character string literals, the array elements have type
char
, and are initialized with the individual bytes of the multibyte character sequence. [....]
Using the aforesaid option makes the string literals const
qualified so using a string literal as the RHS of assignment to a non-const type pointer triggers a warning.
This is done with reference to C11
, chapter §6.7.3
If an attempt is made to modify an object defined with a const-qualified type through use of an lvalue with non-const-qualified type, the behavior is undefined. [...]
So, here the compiler produces a warning for the assignment of const
qualified type to a non-const
-qualified type.
Related to why using -Wall -Wextra -pedantic -std=c11
does not produce this warning, is, quoting the quote once again
[...] These warnings help you find at compile time code that can try to write into a string constant, but only if you have been very careful about using const in declarations and prototypes. Otherwise, it is just a nuisance. This is why we did not make
-Wall
request these warnings.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With