2016-03-19 56 views
0

我如何使用宏作爲函數(聲明在頭 - 源宏)? 我正在尋找這樣的事情(除了這一個不工作)...宏沒有看到標題

了foo.h:

#ifndef FOO_H 
#define FOO_H 

struct bar; 

int bar_isEmpty(struct bar *b); 

#endif /* !defined FOO_H */ 

foo.c的:

struct bar { 
    size_t numElements; 
}; 

#define bar_isEmpty(bar) {bar->numElements == 0} 

正如你所看到的,我不能把宏放在標題中,因爲結構沒有在那裏定義。

+1

您能否提供_「does not work」_的定義? –

+0

我想你不能做這樣的事情。爲什麼不在頭文件中定義宏或定義普通函數是源文件? – MikeCAT

+0

爲什麼不把結構和宏移動到頭文件? –

回答

1

如果您不想將struct bar暴露在對象之外,那麼也無法使用後者向外部展示marco(struct bar)。

這是根據定義,因爲宏只是一種文本替換,在編譯所有宏擴展的結果之前應用之前


BTW,在C這個

int bar_isEmpty(bar *b); 

不會編譯並需要

int bar_isEmpty(struct bar *b); 
+0

謝謝,那就是我一直在尋找的。缺少的* struct *雖然是一個錯誤。將解決。 – LastSecondsToLive

2

有你貼的代碼的幾個問題。

首先,沒有什麼理由首先定義宏。您的標題包含一個函數的原型,並且表示bar_isEmpty應該被定義爲一個函數。每個包含頭文件的c文件都可以使用bar_isEmpty,因此它應該被定義爲一個函數。所以,你的c文件應該是這個樣子:

#include <stddef.h> 
#include "foo.h" 

struct bar { 
    size_t numElements; 
}; 

int bar_isEmpty(struct bar* b) { 
    return b->numElements == 0; 
} 

二是你不包括foo.h(我已經糾正以上)。第三是size_t需要定義 - 這可以通過包括stddef.h(也在上面的例子中完成)來完成。

將其定義爲宏是可以的如果您只打算在foo.c中使用它,或者在頭文件中完全定義了結構。宏的實際定義沒有問題,調用宏時會出現問題。另一方面,在這種情況下,你可能不應該在頭文件中提供一個原型。宏只是文本替換的一個規則,因此您的宏被嚴重定義爲bar_isEmpty(something)會擴展爲{ b->numElements == 0 },這在任何地方都是無效的語法。在這種情況下,正確的定義可能是:

#define bar_isEmpty(b) ((b)->numElements == 0)