C 中的字符串文字与 const char*
Posted
技术标签:
【中文标题】C 中的字符串文字与 const char*【英文标题】:String literals vs const char* in C 【发布时间】:2010-07-21 20:12:40 【问题描述】:为什么 ANSI C 编译器不标记在相应参数没有 const 限定符的函数调用中使用字符串字面量参数?例如,以下代码可能会通过尝试写入只读内存来生成异常。
void somefunc(char buffer[10]);
void somefunc(char buffer[10])
int i;
for (i = 0; i < 10; i++)
buffer[i] = 0;
int main(int argc, char **argv)
somefunc("Literal");
return 0;
这种情况可以在编译时确定,但 VS2010 和 gcc 似乎没有这样做。使用 const char* 参数调用 somefunc 将生成编译器警告。
【问题讨论】:
好问题 - gcc 也没有捕捉到这一点,即使是-Wextra
。
声明一个函数,然后在下一行定义它的意义何在? :)
Hans:我已经修改了问题以指定 ANSI C。无论如何,我并不是建议发出编译器错误。 3 级或 4 级警告只会突出潜在的危险情况。
附注:main
的参数是倒置的,正确的签名是int main(int argc, char *argv[])
。
只是为了澄清-我的问题不是“为什么不将字符串文字视为 const char*?”但是“为什么我们在使用字符串文字参数调用 somefunc() 时不会收到编译器警告?”正如 lunaryorn 指出的那样,函数签名为编译器提供了足够的信息来发出此警告。
【参考方案1】:
这是 K&R 的遗产。修复它会破坏一百万个程序。
【讨论】:
【参考方案2】:gcc:使用标志-Wwrite-strings
PS。 gcc 手册解释了为什么这不是 -Wall 的一部分。无论如何,与往常一样,您应该找到适合您的特定需求和编码风格的 -W 标志组合。例如,在最近的一个项目中,我使用了这样的东西:-Werror -Wall -Wextra -Wformat=2 -Winit-self -Wswitch-enum -Wstrict-aliasing=2 -Wundef -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wcast-align -Wwrite-strings -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline -Wdisabled-optimization -Wunused-macros -Wno-unused
【讨论】:
【参考方案3】:汉斯·帕桑特所说的。 const 在 1989 年被添加为 ANSI 标准的一部分,因此之前的任何内容都没有 const。
【讨论】:
@Georg:我的意思是 const 关键字是在 ANSI C 中添加的,所以用 const 来改造字符串文字已经太迟了。【参考方案4】:字符串文字在 C 中不是 const;在 C++ 中它们是。
编辑:为了消除对我评论的任何混淆,我指的是类型,而不是实际更改它们的能力。
【讨论】:
@Paul,他是对的。 C99 §6.4.5/5:“对于字符串文字,数组元素的类型为char
”未定义修改字符串文字,但元素类型为char
,而不是const char
。
@Matthew:感谢您的澄清-我将“const”解释为“只读”(当然,字符串文字通常在 C 或 C++ 中)但我明白你的意思现在字符串文字的实际 type。【参考方案5】:
如果使用-Wwrite-string
,GNU 编译器(以及英特尔 C 编译器 iirc)将发出警告:
$ gcc -Wall -Wwrite-strings -o foo /tmp/foo.c
/tmp/foo.c: In function 'main':
/tmp/foo.c:12: warning: passing argument 1 of 'somefunc' discards qualifiers from pointer target type
/tmp/foo.c:3: note: expected 'char *' but argument is of type 'const char *'
关于VS2010,我帮不了你。
【讨论】:
酷 - 我想知道为什么-Wwrite-strings
不包含在 -Wall
甚至 -Wextra
中?以上是关于C 中的字符串文字与 const char*的主要内容,如果未能解决你的问题,请参考以下文章
VS2017中遇到不存在从string到const char*的转换函数的解决方法
为啥字符串函数有一些参数作为 const char *(指向常量字符的指针)?
请问C语言如何把2个const char * const s1的字符串合并?