为什么警告要实现指向字符串的指针数组?
Why having warning to implement arrays of pointer to string?
我正在尝试使用指针实现一个字符串数组。以下是我的代码。
#include <stdio.h>
const int MAX = 4;
int main () {
char *names[] = {
"abcd",
"efgh",
"ijkl",
"mnop",
};
int i = 0;
for ( i = 0; i < MAX; i++) {
printf("Value of names[%d] = %s\n", i, names[i] );
}
return 0;
}
我在 运行 时收到警告。以下是警告:
C:\workspace>g++ test_pointer_string_arr.c -o tpsa.exe
test_pointer_string_arr.c: In function 'int main()':
test_pointer_string_arr.c:12:4: warning: deprecated conversion from string const
ant to 'char*' [-Wwrite-strings]
};
^
test_pointer_string_arr.c:12:4: warning: deprecated conversion from string const
ant to 'char*' [-Wwrite-strings]
test_pointer_string_arr.c:12:4: warning: deprecated conversion from string const
ant to 'char*' [-Wwrite-strings]
test_pointer_string_arr.c:12:4: warning: deprecated conversion from string const
ant to 'char*' [-Wwrite-strings]
有什么问题?
C 中的字符串文字是不可变的。任何更改字符串文字内容的尝试都会调用 undefined behavior.
根据定义,字符串具有 char []
类型,因此,通过将 字符串文字 分配给 char *
不会 停止 你不能编写静默调用 UB 的代码。
关于 gcc 选项,-Wwrite-strings
-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.
所以,你需要写
const char *names[] = {
"abcd",
"efgh",
"ijkl",
"mnop",
};
同样如此。
如前所述,大多数时候,可能不值得。
该代码在 C 中完全有效。但是,您显然是为另一种语言编译的:C++。 g++
是 GNU 编译器集合的 C++ 前端。由于 .c
后缀,它可能仍使用 C 模式,但它会启用其他警告。
作为一般规则,您应该使用gcc
来编译C 代码。在这两种语言中,写入字符串文字都是未定义的行为(在任何情况下都应避免)。 C 在执行 const-correctness 方面不那么严格。这就是 gcc 默认为 C 禁用此警告的原因。
因此,如果您不打算更改数组中的字符串,则应始终将指针指向 const char
:
const char *names[] = ...
这有助于编译器检测对条目的非法写入。您还可以使数组本身 const
:
const char * const names[] = ...
这样您就无法更改条目。这不仅对编译器有帮助,而且在某些平台(微控制器)上对将数据存储在不可修改的内存中至关重要。
我正在尝试使用指针实现一个字符串数组。以下是我的代码。
#include <stdio.h>
const int MAX = 4;
int main () {
char *names[] = {
"abcd",
"efgh",
"ijkl",
"mnop",
};
int i = 0;
for ( i = 0; i < MAX; i++) {
printf("Value of names[%d] = %s\n", i, names[i] );
}
return 0;
}
我在 运行 时收到警告。以下是警告:
C:\workspace>g++ test_pointer_string_arr.c -o tpsa.exe
test_pointer_string_arr.c: In function 'int main()':
test_pointer_string_arr.c:12:4: warning: deprecated conversion from string const
ant to 'char*' [-Wwrite-strings]
};
^
test_pointer_string_arr.c:12:4: warning: deprecated conversion from string const
ant to 'char*' [-Wwrite-strings]
test_pointer_string_arr.c:12:4: warning: deprecated conversion from string const
ant to 'char*' [-Wwrite-strings]
test_pointer_string_arr.c:12:4: warning: deprecated conversion from string const
ant to 'char*' [-Wwrite-strings]
有什么问题?
C 中的字符串文字是不可变的。任何更改字符串文字内容的尝试都会调用 undefined behavior.
根据定义,字符串具有 char []
类型,因此,通过将 字符串文字 分配给 char *
不会 停止 你不能编写静默调用 UB 的代码。
关于 gcc 选项,-Wwrite-strings
-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.
所以,你需要写
const char *names[] = {
"abcd",
"efgh",
"ijkl",
"mnop",
};
同样如此。
如前所述,大多数时候,可能不值得。
该代码在 C 中完全有效。但是,您显然是为另一种语言编译的:C++。 g++
是 GNU 编译器集合的 C++ 前端。由于 .c
后缀,它可能仍使用 C 模式,但它会启用其他警告。
作为一般规则,您应该使用gcc
来编译C 代码。在这两种语言中,写入字符串文字都是未定义的行为(在任何情况下都应避免)。 C 在执行 const-correctness 方面不那么严格。这就是 gcc 默认为 C 禁用此警告的原因。
因此,如果您不打算更改数组中的字符串,则应始终将指针指向 const char
:
const char *names[] = ...
这有助于编译器检测对条目的非法写入。您还可以使数组本身 const
:
const char * const names[] = ...
这样您就无法更改条目。这不仅对编译器有帮助,而且在某些平台(微控制器)上对将数据存储在不可修改的内存中至关重要。