标头没有看到宏

时间:2016-03-19 09:25:52

标签: c macros c-preprocessor

如何将宏用作函数(在头文件中声明 - 源代码中的宏)? 我正在寻找类似的东西(除了这个不起作用)......

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}

正如您所看到的,我无法将宏放入标题中,因为该结构尚未定义。

2 个答案:

答案 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);