假设我有一个特殊的头文件,它被设计成包含多次,并根据包含宏之前必须定义的某个宏的值生成不同的代码。例如,以下文件dumb.h
:
#define RETFUNC return_ ## VALUE
static inline int RETFUNC() {
return VALUE;
}
包括:
#define VALUE 100
#include "dumb.h"
#define VALUE 200
#include "dumb.h"
它生成两个版本的函数,如:
static inline return_100 {
return 100;
}
static inline return_200 {
return 200;
}
太棒了。
如何为此类文件制作头保护程序?如果没有保护,如果头文件的两个不同使用者都请求相同的
VALUE
,则会出现错误,因为将生成两个相同版本的return_*
函数。现在一个普通的头球后卫像:
#ifndef DUMB_H_
#define DUMB_H_
...
#endif // DUMB_H_
无法工作,因为它只能有效地包含一次文件(上面的
#include
序列将生成函数的_100
版本,而不是_200
版本)。原则上,我希望使用标记粘贴来生成宏的名称,以作为保护进行检查,例如:
#ifndef DUMB_H_ ## VALUE
#define DUMB_H_ ## VALUE
...
但标记粘贴不能像这样使用(在宏扩展之外)。
是否有任何其他选项可以防止此文件与同一个
VALUE
一起被多次包含,但仍允许针对每个不同的VALUE
请求有效地包含正文一次?1这不是一个好的模式或类似的模式,但至少在它看来是可行的。
最佳答案
根据comment 1和comment 2中的解释,我认为正常的过程更像这样。我将使用一个类型作为参数,并为不同类型生成一个“minimum”函数:dumb.h
#ifndef DUMB_H_INCLUDED
#define DUMB_H_INCLUDED
#define MIN_TYPE(x) \
static inline x min_ ## x(x v1, x v2) { return (v1 < v2) ? v1 : v2; }
#endif /* DUMB_H_INCLUDED */
消费者代码
#include "dumb.h"
#include <inttypes.h>
MIN_TYPE(int) // No semicolon; no empty declaration!
MIN_TYPE(double)
MIN_TYPE(uint64_t)
void write_minima(int i1, int i2, double d1, double d2, uint64_t u1, uint64_t u2)
{
printf("Minima: (%d, %g, %" PRIu64 ")\n",
min_int(i1, i2), min_double(d1, d2), min_uint64_t(u1, u2));
}
这并不能阻止您尝试在一个TU(翻译单元)中实例化同一个函数两次,但是如果您这样做,编译器将反对。坦率地说,让编译器做抱怨比让C预处理器发现你搞错了并改正错误要简单得多。
如果C代码将由另一个程序生成,则需要确保代码生成器跟踪它所请求的内容,并确保它不会重复生成代码。
关于c - 带防护的包含在内的 header ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47706465/