Consider this C code:
void foo(char *);
void bar(void) {
foo("");
}
When I compile that with -pedantic -Wall -Wextra with GCC or Clang, or with -Weverything with Clang, it compiles without giving me any relevant warnings. If I add -Wwrite-strings, then GCC gives me this:
<source>:4:9: warning: passing argument 1 of 'foo' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
4 | foo("");
| ^~
<source>:1:10: note: expected 'char *' but argument is of type 'const char *'
1 | void foo(char *);
| ^~~~~~
And clang gives me this:
<source>:4:9: warning: passing 'const char [1]' to parameter of type 'char *' discards qualifiers [-Wincompatible-pointer-types-discards-qualifiers]
foo("");
^~
<source>:1:16: note: passing argument to parameter here
void foo(char *);
^
Lots of things seem wrong here to me:
-Wdiscarded-qualifiers, but if I pass that instead of -Wwrite-strings, I don't get that warning.-Weverything meant "literally every single warning the compiler knows about", but this seems to contradict that.What's going on here? Why does this particular warning seem so buggy?
In C, string literals existed before const did. So C string literals were not const-qualified (although the results of attempting to write to them are not defined by the C standard). If string literals were made const-qualified, much old software would break due to type errors. The C committee has decided this change is not worthwhile.
The switch -Wwrite-strings is not really a warning switch, in spite of -W. It changes the language being compiled to a non-standard C in which string literals are const-qualified. (There is a bug report that it is a mistake for GCC to categorize this as a warning switch.) This explains why GCC shows a -Wdiscarded-qualifier when a string literal is assigned to a char *, and it also explains why -Wdiscarded-qualifier alone does not trigger these warnings—because without -Wwrite-strings, the string literal is not const-qualified, so no qualifier is being discarded by the assignment.
Presumably Clang’s -Weverything does not include -Wwrite-strings because, as noted above, it is not truly a warning option and because it changes the language to non-standard C.
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