【问题标题】:Why gcc does not give a warning when you initialize an array without const with strings?为什么使用字符串初始化没有 const 的数组时 gcc 不给出警告?
【发布时间】:2016-10-09 22:54:40
【问题描述】:
#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;
}

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

当将const char 传递给在print(constArray); 中接收char 的函数时,换句话说,将const char“转换”为char,编译器确实会给我一个警告。我希望编译器在这两种情况下都给我一个警告,或者都不给我一个警告,但不是在一种情况下,也不是在另一种情况下。

我认为这个警告对于防止出现array[0][0] = '!'; 中的错误很重要。那么为什么我在第一次初始化时没有收到警告呢?

【问题讨论】:

  • 即使字符串是只读的,指针也不是。可以在没有任何警告的情况下更改它们,这没关系。
  • @tofro,是的,但这不是重点。 const char * 类型的值不能分配给char * 类型的左值——它违反了标准的第 6.5.16/1 段。这里的问题部分是“只读”是对字符串文字的糟糕描述,并且无论如何它都不等同于const。该标准并没有说字符串文字是只读的;它说试图修改它们的值会产生未定义的行为。这是一个很好但很重要的区别。

标签: c gcc casting constants warnings


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多