2017-03-23 116 views
0

這使我困擾。它給我一個警告如何將字符串值傳遞給函數C

passing argument 1 of ‘funcName’ discards qualifiers from pointer target type 

但是,程序運行得很好,並打印提交的值。

的功能如下

void funcName(char *str) { 
    printf("%s", str); 
} 

void main() { 
    funcName("Hello world"); 
} 

產量世界,你好。

+1

你是怎麼想的警告聲明帳戶?請發佈編輯線! –

+0

@Sleek 13--您的問題與啓用了哪些編譯器警告有關。字符串文字不是'const',而是'char []'類型。用UB修改字符串文字,用GCC標誌'-Wwrite-strings'啓用這個警告。你使用什麼編譯器,調用是什麼? –

回答

5

這是因爲"Hello, world"是恆定的,所以更改功能

void funcName(const char *text) 
{ 
    printf("%s\n", text); 
} 

字符串字面量是不變的,它們存儲在你的程序的只讀存儲器部分,通過該指針沒有const意味着你可以不小心修改它在目標函數內部,如果這樣做,那會導致未定義的行爲,並且編譯器試圖保護你免受這種情況的影響。

而且,void main()不是main()符合標準的有效簽名,你可以找到它的舊書,以前的標準,但現在它不再被接受,認可和標準簽名

  • int main(void)如果你不處理命令行參數。
  • int main(int argc, char **argv)處理存儲在argv中的argc參數,該參數在命令行中傳遞。
+0

對於OP原始代碼(固定簽名爲'main()'並添加了'#include '),我在GCC 4.9中沒有得到任何警告,其中'gcc -std = c99 -Wall -Wextra -Wpedantic'。 –

+0

至少有一個'void main()'的警告!如果傳遞'-std = c99',應該是一個錯誤。 –

+0

@DavidBowling事實上,這個'錯誤:'main'的返回類型不是'int'[-Werror = main]',它直接是一個錯誤,而不是一個警告。 –

2

看來問題是這個C程序被編譯爲一個C++程序。

在C++中,字符串文字具有常量字符數組的類型。因此,如果在C++程序中將字符串文字作爲參數提供給具有不帶限定符常量的相應參數的函數,則編譯器將發出消息。

如果要將程序編譯爲C程序,則代碼是有效的,因爲在C字符串中文字具有非常量字符數組的類型,編譯器不應該發出相對於限定符的診斷消息。

但在任何情況下,最好聲明函數像

void funcName(const char *str); 
       ^^^^^^ 

,因爲在這種情況下,該功能的用戶可以肯定的是傳遞給函數的字符串將不會改變。

考慮到,主要功能不帶參數應當用C像

int main(void) 
+0

儘管有幾個請求,OP還沒有提供編譯的細節。儘管如此,我相信這是正確的答案,並且你有我的紫外線。這似乎是一個很重要的細節,你提到C中的字符串不是'const'。我曾嘗試用g ++編譯OP代碼,並得到'警告:不贊成將字符串常量轉換爲'char *'[-Wwrite-strings]';並不完全是OP提到的警告,而是相關的。 –

相關問題