2010-07-21 73 views
9

为什么ANSI C编译器在函数调用中不标记字符串文字参数的使用,其中相应的参数没有const限定符?例如,以下代码可能会通过尝试写入只读内存来生成异常。C中的字符串常量与常量字符*

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将生成编译器警告。

+0

好问题 - 即使使用'-Wextra',gcc也无法捕捉到这个问题。 – 2010-07-21 20:21:47

+0

声明一个函数的意义是什么,然后定义它的下一行? :) – GManNickG 2010-07-21 20:27:54

+0

汉斯:我已经修改了这个问题来指定ANSI C.无论如何,我并不是建议发布编译器错误。 3级或4级警告只会突出显示潜在的危险情况。 – Robin 2010-07-21 20:35:24

回答

11

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

6

字符串文字在C中不是常量;在C++中他们是。

编辑:为了澄清关于我的评论的任何混淆,我指的是类型,而不是实际改变它们的能力。

+1

是什么让你觉得呢? – 2010-07-21 20:24:49

+2

@保罗,他是对的。 C99§6.4.5/ 5:“对于字符串文字,数组元素的类型为”char“”它未定义为修改字符串文字,但元素类型为“char”,而不是“const char”。 – 2010-07-21 22:59:38

+0

@Matthew:感谢您的澄清 - 我正在将“const”解释为“只读”(当然,字符串文字通常以C或C++编写),但我明白您对字符串的实际*类型的含义现在的文字。 – 2010-07-22 07:08:38

15

这是一个传统的K &。修复它将破坏一百万个程序。

7

Hans Passant说了什么。 1989年,const被添加为ANSI标准的一部分,所以之前的任何东西都没有const。

+1

@Georg:我的意思是在ANSI C中添加了const关键字,所以使用常量来修改字符串文字已经太晚了。 – ninjalj 2010-07-21 20:30:37

+0

啊,现在我找你:) – 2010-07-21 20:39:33

4

GNU编译器(和英特尔的C编译器为好,IIRC)会发出警告,如果-Wwrite-string使用:

$ 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,我无法帮到你。

+1

酷 - 我想知道为什么'-Wwrite-strings'不包含在'-Wall'或甚至'-Wextra'中? – 2010-07-22 07:09:42