2010-08-30 110 views
156

在C代碼中抑制未使用的參數警告的最佳方法是什麼?「未使用的參數」警告C

例如,

Bool NullFunc(const struct timespec *when, const char *who) 
{ 
    return TRUE; 
} 

在C++中,我能夠把/*...*/評論周圍的參數。但當然不是。

它給我error: parameter name omitted

+0

可能的重複[什麼是最好的方法來抑制「未使用變量x」 - 警告](http://stackoverflow.com/questions/3417837/what-is-the-best-way-to-supress-unused -variable-x-warning) – 2014-09-17 07:14:04

+3

@CiroSantilli這個問題有更多upvotes,最好將其他問題標記爲重複。 – sashoalm 2015-01-20 13:18:42

+1

另請參見[此問題的C++版本](http://stackoverflow.com/q/1486904/1708801) – 2015-07-28 19:58:34

回答

227

我平時寫這樣一個宏:

#define UNUSED(x) (void)(x) 

您可以使用此宏爲您的所有未使用的參數。 (請注意,這適用於任何編譯器。)

例如:

void f(int x) { 
    UNUSED(x); 
    ... 
} 
+23

我只是使用(void)x直接 – 2012-05-30 11:27:17

+0

+1。最後一個便攜式解決方案。 – Jack 2012-11-07 02:24:18

+5

雖然這是AFAIK的唯一便攜式方式,但如果稍後使用該變量,則可能會引起誤解,並忘記ro刪除未使用的行。這就是爲什麼GCC的__unused__很好。 – ideasman42 2012-11-07 13:58:58

73

在海灣合作委員會,你可以標記與unused attribute參數。

該屬性,連接到一個變量,表示該變量是 意味着是可能未使用。 GCC不會爲此 變量產生警告。

實際上,這是通過在參數後面加上__attribute__ ((unused))來實現的。例如

auto lambda = [](workerid_t workerId) -> void { }; 

成爲

auto lambda = [](__attribute__((unused)) _workerid_t workerId) -> void { } ; 
+14

對於像我這樣的新手來說,這意味着將'__attribute__((未使用))'放在參數前面。 – josch 2014-09-19 05:53:31

+1

@josch我認爲你是完全正確的,但文檔似乎暗示它應該放在參數後面*。這兩個選項都可能支持沒有問題。 – Antonio 2015-04-24 09:43:06

2

我已經看到了這種風格beeing使用:

if (when || who || format || data || len); 
+13

嗯。我不能說我喜歡這個,因爲這裏假定所有涉及的參數都可以轉換成布爾值。 – Suma 2011-12-21 07:05:07

+0

這並不是一個很好的約定,儘管編譯器幾乎可以肯定會優化它,但它不太清楚會發生什麼情況,並可能會混淆靜態源代碼檢查器。在這裏恕我直言,更好地使用其他建議之一。 – ideasman42 2012-10-31 04:08:03

+1

我不相信我仍然得到這個答覆。這個問題表明這是針對C的。是的,在另一種語言中這是行不通的。 – Iustin 2013-03-17 14:11:52

51

您可以使用gcc /鐺未使用的屬性,但是我在標題中使用這些宏爲了避免在源代碼中使用gcc特定的屬性,在每個地方都有一個有點冗長/醜陋的地方。

#ifdef __GNUC__ 
# define UNUSED(x) UNUSED_ ## x __attribute__((__unused__)) 
#else 
# define UNUSED(x) UNUSED_ ## x 
#endif 

#ifdef __GNUC__ 
# define UNUSED_FUNCTION(x) __attribute__((__unused__)) UNUSED_ ## x 
#else 
# define UNUSED_FUNCTION(x) UNUSED_ ## x 
#endif 

然後你就可以做...

void foo(int UNUSED(bar)) { ... } 

我喜歡這個,如果你嘗試在代碼中使用bar任何地方,所以你不能錯誤地離開屬性,因爲你得到一個錯誤。

和功能...

static void UNUSED_FUNCTION(foo)(int bar) { ... } 

注1):
據我所知,MSVC沒有一個相當於__attribute__((__unused__))

注2):
UNUSED宏將不包含括號參數工作,
所以如果你有一個參數像float (*coords)[3]不能做,
float UNUSED((*coords)[3])float (*UNUSED(coords))[3],這是唯一的缺點UNUSED宏,我發現到目前爲止,在這些情況下,我回落到(void)coords;

+0

或者可能只是'#define __attribute __(x)'爲非GCC環境(AFAIK MSVC不支持__attribute__')? – 2017-11-10 06:16:49

+0

這可以工作,但dunder的前綴是爲編譯器保留的,所以我寧願避免這種情況。 – ideasman42 2017-11-10 11:22:10

+0

對於我的gcc,至少在標識符似乎適用於funcs,vars和參數之前放置屬性說明符,所以類似#define POSSIBLY_UNUSED(identifier)__attribute __((__ unused__))標識符可用於所有三個 – 2018-03-02 22:01:36

0

爲了記錄在案,我喜歡工作的回答以上,但我很好奇的解決方案只是一個使用變量名本身「無所事事「的狀態nt:

void foo(int x) { 
    x; /* unused */ 
    ... 
} 

當然,這有缺點;例如,沒有「未使用」的註釋,它看起來像是一個錯誤,而不是有意識的代碼行。

好處是,不需要DEFINE,它可以擺脫警告。

是否有任何性能,優化或其他差異?

+2

我用這與MSVC,但GCC引發「聲明無效」警告。所以,Job的解決方案就是要走的路。 – 2013-05-14 06:32:21

14

與未使用的屬性GCC:

int foo (__attribute__((unused)) int bar) { 
    return 0; 
} 
4

標註屬性是理想的方式。 MACRO導致混亂。 並通過使用void(x),我們在處理中增加了開銷。

如果不使用輸入參數,如果不使用該功能

​​

內定義的變量現在在以後使用散列變量爲你的邏輯,但並不需要BKT使用

void foo(int __attribute__((unused))key) 
{ 
} 

。定義BKT爲未使用,否則編譯器says'bkt設置BT不使用」

注意:這只是相應的警告不是優化

2

我得到了同樣的問題,我用第三件庫當我編譯這個庫,編譯器(GCC /鐺)會抱怨未使用的變量

像這樣

TEST.CPP:29:11:警告:變「魔術」設置,但不使用[-Wunused-but-set-variable] short magic [] = {

test.cpp:84:17:warning:unused variable'before_write'[-Wunused-variable] int64_t before_write = Thread :: currentTimeMillis();

所以解決方案很清楚。作爲gcc/clang添加-Wno-unused CFLAG將抑制所有「未使用」警告,即使您認爲已設置了-Wall

通過這種方式,您不需要更改任何代碼。

+1

這很好,如果你真的想忽略所有未使用的警告,但幾乎從來沒有這樣。它通常只是您想忽略的特定實例。 – Dan 2016-11-05 18:07:31

4

一個gcc /克++抑制爲源代碼中的塊中的未使用的參數的警告特定的方式與如下pragma語句它括:

#pragma GCC diagnostic push 
#pragma GCC diagnostic ignored "-Wunused-parameter" 
<code with unused parameters here> 
#pragma GCC diagnostic pop 
+0

Clang支持這些診斷編譯以及https://clang.llvm.org/docs/UsersManual.html#controlling-diagnostics-via-pragmas – eush77 2017-04-28 15:49:28

+0

優秀的答案。非常感謝。 – pylover 2018-01-28 12:00:19

0

在MSVC抑制特定警告它足以指定編譯器的編號爲/ wd#。我的CMakeLists.txt包含這樣的塊:

If (MSVC) 
    Set (CMAKE_EXE_LINKER_FLAGS "$ {CMAKE_EXE_LINKER_FLAGS}/NODEFAULTLIB: LIBCMT") 
    Add_definitions (/W4 /wd4512 /wd4702 /wd4100 /wd4510 /wd4355 /wd4127) 
    Add_definitions (/D_CRT_SECURE_NO_WARNINGS) 
Elseif (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_GNUC) 
    Add_definitions (-Wall -W -pedantic) 
Else() 
    Message ("Unknown compiler") 
Endif() 

現在我不能說究竟是什麼/ wd4512/wd4702/wd4100/wd4510/wd4355/wd4127的意思,因爲我不關注任何MSVC三年,但他們壓制不會影響結果的超級警告。