2016-03-20 78 views
2

我在我的代碼,一個警告,讓我發瘋了:糾正「格式字符串不是一個字符串常量」警告

int vasprintf_wrapper(char** bufptr, const char* fmt, va_list ap) 
{ 
    // Do stuff... 
    // ... 
    return vasprintf(bufptr, fmt, ap); 
} 

鏘(3.6.0),抱怨與「格式字符串不是一個字符串文字「,指的是被轉發的fmt參數。

天真,我想:

return vasprintf(bufptr, reinterpret_cast<const char[]>(fmt), ap); 

這當然不能編譯。

我該怎麼辦?完全禁用警告不是一種選擇。我想要警告。但在這種情況下,我想告訴編譯器,我知道自己在做什麼(「有名的遺言」旁邊的笑話......)

+0

可能,我不是100%肯定的,但我不明白這是一個有效的CONSTANT,因爲你傳遞了一個變量(所以它不能成爲一個合適的賦值)。您是否嘗試刪除該部分? –

+0

@DavyC你的意思是演員?是的,同樣的結果有或沒有'const'。 –

回答

4

你可以告訴鏘既然你不想把這一警告完全關閉,您可以使用下面的代碼在本地禁用此警告您的參數是使用屬性標誌的printf樣式格式。見the documentation

在你的情況,這樣的事情應該工作:

__attribute__((__format__ (__printf__, 2, 0))) 
int vasprintf_wrapper(char** bufptr, const char* fmt, va_list ap) 
{ 
... 
} 

編輯:改變了最後一個參數爲0,按照玉米稈建議(關閉檢查va_list參數)。

+0

我認爲它應該是'__attribute __((__ format__(__printf__,2,0)))''。 [GCC文檔](https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes)說:「*對於無法檢查參數的函數如vprintf),將第三個參數指定爲零*「但是我喜歡你的方法比我的更好,因爲它在使用'vasprintf_wrapper'時保留了警告,所以+1。 – Cornstalks

+0

謝謝!我不記得'__format__'屬性甚至存在。 Cornstalks的建議(最後一個參數爲0)有效。用3不編譯。 –

4

啓用此類警告的警告標誌是-Wformat-nonliteral

#pragma clang diagnostic push 
#pragma clang diagnostic ignored "-Wformat-nonliteral" 

... 

#pragma clang diagnostic pop 

所以,你的功能應該是這樣的:

int vasprintf_wrapper(char** bufptr, const char* fmt, va_list ap) 
{ 
    // Do stuff... 
    // ... 

#pragma clang diagnostic push 
#pragma clang diagnostic ignored "-Wformat-nonliteral" 
    return vasprintf(bufptr, fmt, ap); 
#pragma clang diagnostic pop 
} 
+0

謝謝。對於記錄來說,這工作得很好,但事實證明'__format__'屬性,正如另一個答案中提到的那樣,實際上會將編譯時檢查推送給調用者,這意味着只有在調用函數時纔會發出警告與非文字,而不是無條件散發。所以這兩個答案的工作,屬性更安全,所以我選擇了一個:-) –

+0

@NikosC。好,你應該選擇其他答案:)這比我的好。儘管有人認爲它很有用,但我會把它留在這裏。 – Cornstalks

相關問題