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的字符串合并?

为啥文字不是 const (字符串除外)?

const char []和const char之间的区别*

const char array (c style string) 模板特化