2017-07-19 400 views
-1

我有一個C代碼,我有這條線。sprintf_s()隱式聲明警告

sprintf_s(var, outfile_ppm, local_filecounter++); 

這裏,var是char類型,local_filecounter是int類型。

當我運行代碼,它給了我這樣的警告:

警告:函數「sprintf_s」隱式聲明是無效的C99 [-Wimplicit函數聲明]

是什麼這個警告,我該如何擺脫它?

+2

「我該如何擺脫它?」 - >不要使用'sprintf_s()'發佈看起來需要它的代碼來查看備選方案。 – chux

+0

我需要使用它。 – npatel

+0

快速&骯髒的方式:添加'-Wnoimplicit-function-declaration'到編譯器選項。 – ForceBru

回答

4

sprintf_s函數是附件K/TR 24731邊界檢查接口的一部分。但是,對這些接口感興趣的人應閱讀N1967 Field Experience With Annex K — Bounds Checking Interfaces。下面是摘錄:

儘管從原來的建議十餘年,自ISO/IEC TR 24731-1的批准近十年:2007年,由於引入了邊界檢查接口的將近五年進入C標準,沒有出現可行的符合實現。 API仍然存在爭議,實施者仍然拒絕執行請求。

事實上,如果你看一下GCC C11 status page,你會看到(強調):

邊界檢查(附錄K)[可選]:圖書館問題(未實現)

附錄K(sprintf_s和其他類似_s版本的函數)的唯一主要實現是在Visual Studio中。給出的流行解釋是微軟在他們自己的代碼庫內部使用這些函數來解決安全問題。其他實現依賴於像Valgrind,mudflap,地址清理器等工具來解決同樣的問題,並且微軟以外的代碼庫實際上並沒有使用這些函數,所以實現它們的動機很小。

換句話說,如果您不使用Visual Studio,則無法使用這些功能。幸運的是,它們不是必需的。

sprintf_s在問題的調用是高度懷疑與...

// Wait, what? Something smells fishy... 
sprintf_s(var, outfile_ppm, local_filecounter++); 

開始的第三個參數sprintf_s應該是一個格式字符串,但local_filecounter++看起來太可疑是一個格式字符串。

通常情況下,您可以使用snprintf,將其輸出截斷以適應緩衝區,如果您使用C標準之外的函數,則可以使用asprintf

char var[256]; 
snprintf(var, sizeof(var), outfile_ppm, localfile_counter++); 

注意,如果var沒有數組類型,你不能使用sizeof(var)使用時,作爲函數的參數適用於這裏來計算它的大小,以及約腐爛數組的指針通常的注意事項。

摘要:除非切換到Visual Studio或自己實現,否則不能使用sprintf_s()。堅果餅乾。

小注:從理論上講,如果你想sprintf_s,你應該定義__STDC_WANT_LIB_EXT1__。然而,在實踐中,只要我知道,無論宏的存在如何,定義sprintf_s的所有都是如此。事情可能已經改變。