为什么 gcc 在初始化没有使用字符串 const 的数组时不发出警告?

Wat*_*oll 3 c gcc warnings casting constants

#include <stdio.h>

void print(char *strings[]) {
  while (*strings) printf("%s\n", *strings++);
}

int main(int argc, char *argv[]) {

  char *array[] = {"Hello", "World", NULL}; // No warning?
  const char *constArray[] = {"Hello", "World", NULL};

  print(constArray); // Warning!

  //constArray[0][0] = '!'; Compile time error
  array[0][0] = '!'; // Run time error

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我期待收到警告,char *array[] = {"Hello", "World", NULL};因为这些字符串的字符是只读的,但编译器没有给我警告。所以基本上编译器让我在没有警告的情况下“强制转换”const char到 a char

将 a 传递const char给接收 a charin的函数时,print(constArray);换句话说,将 aconst char传递给 a 时char,编译器确实给了我一个警告。我希望编译器在两种情况下都会给我警告,或者两种情况都没有,但不是在一种情况下,而是在另一种情况下。

我认为此警告对于帮助防止array[0][0] = '!';. 那么为什么我在第一次初始化时没有收到警告?

Joh*_*ger 5

那么为什么我在第一次初始化时没有收到警告?

因为字符串文字的类型是 array of char,而不是 array of const char,尽管修改这样的数组的元素会产生未定义的行为。这源于 C 的最初几天,当时没有const. 我确信它在现代 C 中的持久性围绕着如果类型改变会出现的不兼容的程度和范围。

但是,对于单个程序,GCC 可以帮助您。如果您打开它的-Wwrite-strings选项,那么它确实会给出字符串文字 type ,结果是您提供的结构会引发警告。const char [length]