如何将宏用作函数(在头文件中声明 - 源代码中的宏)? 我正在寻找类似的东西(除了这个不起作用)......
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}
正如您所看到的,我无法将宏放入标题中,因为该结构尚未定义。
答案 0 :(得分: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)
答案 1 :(得分:1)
如果您不想将struct bar
暴露给对象外部,那么也无法使用后者(struct bar
)将marco暴露给外部。
根据定义,这是一个宏只是一种文本替换,在之前应用编译所有宏扩展的结果。
BTW,在C中
int bar_isEmpty(bar *b);
不会编译,需要
int bar_isEmpty(struct bar *b);