2015-04-22 38 views
1

考慮下面的代碼示例:格式說明

#define STRING_LITERAL "%u, %u" 
const char string_const[ ] = "%u, %u"; 

snprintf(dest_buff, sizeof(dest_buff), STRING_LITERAL, arg1, arg2, arg3); 

我的編譯器則發出警告:

snprintf(dest_buff, sizeof(dest_buff), string_const, arg1, arg2, arg3); 
:如果我改變指令,這種說法

之前的格式字符串結尾現在

然後編譯器沒有發出警告。

我的問題是:這樣的行爲是否符合C99標準?

+1

C99是否要求符合規範的編譯器根據無效的printf()調用(或任何其他可變參數調用)發出警告? – user3125367

回答

1

警告是由編譯器生成的,它能夠確定您向調用傳遞了不正確的參數,並且不在第二次。

該標準定義了傳遞不正確的參數和/或使用不正確的標誌會導致未定義的行爲。

標準不要求此警告,它只是程序員的附加幫助。

1

我的問題是:這樣的行爲是否符合C99標準?

這兩個示例調用未定義的行爲,但沒有違反約束或語法規則,因此不需要診斷。

0

你有太多的爭論,應該是:

#define STRING_LITERAL "%u, %u" 
snprintf(dest_buff, sizeof(dest_buff), STRING_LITERAL, arg1, arg2); 

或:

#define STRING_LITERAL "%u, %u, %u" 
snprintf(dest_buff, sizeof(dest_buff), STRING_LITERAL, arg1, arg2, arg3); 

的原因缺乏警告的是,它是不確定的行爲,並警告只發出時編譯器足夠聰明,可以認爲出了什麼問題。如果字符串直接在snprintf命令中,那麼編譯器看起來非常聰明,如果字符串是間接傳遞的,它看起來不是。

+2

呃......這個問題如何回答?是不是像OP已經知道這一點? –

+0

你是對的,我已經添加了一個說明 –

0

在這個例子中

snprintf(dest_buff, sizeof(dest_buff), STRING_LITERAL, arg1, arg2, arg3); 

你直接字面傳遞字符串,而在這其中

snprintf(dest_buff, sizeof(dest_buff), string_const, arg1, arg2, arg3); 

你傳遞一個變量。

我假設你的編譯器(不管是哪一個)爲了所討論的警告的目的而將文字與變量區分開來。

0

我在C99標準的附件I(常見警告)中找到了以下聲明,以澄清情況。

1在很多情況下,執行過程可能會產生警告,其中沒有一個是作爲本國際標準的一部分指定的 。以下是一些更常見的情況。