2010-07-21 102 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