【发布时间】:2026-02-12 01:55:02
【问题描述】:
假设我有一个特殊的头文件,它被设计为多次包含,并根据某些宏的值生成不同的代码,这些宏必须在包含它之前定义。比如下面的文件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;
}
太棒了1。
如何为这种类型的文件制作标头保护?如果没有保护,如果头文件的两个不同使用者都请求相同的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 不是伟大,因为这是一个很好的模式或类似的东西,但它至少看起来有效。
【问题讨论】:
-
我想这里有一个XY Problem。即使假设真正的函数比这里显示的更复杂,为什么数字不是函数的参数?您如何使功能有所不同?或者您是否需要一个函数指针来包装一个常量以供在某处使用,并且与 C++ 不同的是,您不能创建一个具有存储记录数字并提供函数指针的对象。
-
@JonathanLeffler - 是的,实际情况更复杂。这是一个 MCVE 来说明这个问题。显然我实际上并不想生成像
return_100这样的函数。VALUE不一定是数字,但可能不能简单地传递给函数(例如,类型)。多重包含模式有时很有用,因此我对该问题的特定解决方案感兴趣,即使其他一些潜在问题承认完全不同的解决方案。也就是说,我很了解 XY,但在这里我主要对这个狭隘的问题感兴趣。 -
当所谓的“受保护的头文件”以相同的 VALUE 被多次包含时,您预计会发生什么。编译错误?即使你没有守卫,如果你定义了两个同名的函数,也会抛出链接错误。
-
@aneeshjose - 不,在这种情况下,对于给定的
VALUE,它应该只包含一次,如问题末尾所述。在上面的 MCVE 中,它会为每个调用它的不同VALUE生成一个return_*函数。 -
理想情况下,您的澄清 cmets 应该是对问题的更新。
标签: c c-preprocessor c11