2010-11-03 32 views
11

我已經經歷了一些C源代碼,我注意到以下幾點:怪異使用無效

void some_func (char *foo, struct bar *baz) 
{ 
    (void)foo; 
    (void)baz; 
} 

爲什麼在這裏使用void?我知道(void)之前,一個表達式明確指出的值被丟掉了;但有人可以向我解釋這種用途的基本原理嗎?

回答

22

此代碼可確保您不會收到有關foo和baz未被使用的編譯器警告。

+0

雖然他們可以留作'TODO'提醒。 – ruslik 2010-11-03 02:44:34

+1

它可能不是一種遺留的東西TODO:這可能是代碼的最終狀態。例如,這個函數可能是一個回調函數,並且這些參數確實沒有被使用。 – 2010-11-03 02:46:44

+1

「確保」有點過於強大。它適用於一些編譯器,但顯然它不是通用的:http://herbsutter.com/2009/10/18/mailbag-shutting-up-compiler-warnings/ – jamesdlin 2010-11-03 02:48:39

8

最有可能的是,有人正在用編譯器構建此代碼,該編譯器發出未使用參數的警告,並想要禁止警告。

6

這些變量出現在函數中最可能的原因是刪除關於未使用的參數的任何警告。

但是,由於這可能會引入另一個警告(因爲您可能使用的警告級別高於正常水平),因此作者還採取了額外的措施來刪除這些警告。

在C中,聲明

42; 

實際上是有效的,雖然不是非常有用的。如果你編譯:

int main (void) { 
    42; 
    return 0; 
} 

它不會抱怨(通常)。但是,如果您編譯與gcc -Wall -pedantic(例如),你會得到這樣的:

prog.c: In function `main': 
prog.c:2: warning: statement with no effect 

因爲編譯器,這是正確的,他認爲你瘋了。

將一個(void)強制轉換爲生成值的東西,例如42;將明確聲明您不關心該值。

我已經看到了這個上堅持認爲,因爲像printf一個函數實際上返回一個值,你一定是瘋了忽略它,導致這些暴行一些肛門保持編譯器使用:

(void)printf ("Hello, world.\n"); 
(void)strcpy (dest, src); 

:-)


舉例來說,如果你編譯:

void some_func (char *foo) {} 
int main (void) { some_func (0); return 0; } 

gcc -Wall -W -pedantic,你會得到:

warning: unused parameter `foo' 

如果 「使用」 的參數:

void some_func (char *foo) { foo; } 

你會得到

warning: statement with no effect 

但是,如果您使用的參數和明確地忽略結果:

void some_func (char *foo) { (void)foo; } 

根本沒有任何警告。

+0

我知道這個用法(調用一個函數返回一些東西,並在它前面粘上一個'(void)'來忽略返回的值);我只是很好奇爲什麼會這樣做的爭論。 – sanjoyd 2010-11-03 03:02:00

+0

@theDigtialEngel,請參閱更新。簡單地提一下函數中的參數會將另一個警告替換爲另一個警告。你必須廢除它以擺脫第二個警告。 – paxdiablo 2010-11-03 03:11:58

+0

事實上,你可以走得更遠,只需要刪除參數名稱:void some_func(char *){}'從http://herbsutter.com/2009/10/18/mailbag-shutting-up-compiler-警告/,發佈在jamesdlin的評論中。把它變成'模板 void ignore(T const&){}'並且你有一個很好的通用忽略器! :) – 2010-11-04 02:56:55