简体   繁体   English

带防护的包含在内的标头

[英]Multiply-included header with guards

Let's say I have a special header file which is designed to be included multiple times and generates different code depending on the value of some macro which must be defined before including it. 假设我有一个特殊的头文件,该头文件设计成可多次包含,并根据某些宏的值生成不同的代码,这些宏必须在包含宏之前定义。 For example, the following file dumb.h : 例如,以下文件dumb.h

#define RETFUNC return_ ## VALUE
static inline int RETFUNC() {
  return VALUE;
}

You include it like: 您像这样包含它:

#define VALUE 100
#include "dumb.h"
#define VALUE 200
#include "dumb.h"

and it generates two versions of the function like: 并生成该函数的两个版本,例如:

static inline return_100 {
  return 100;
}

static inline return_200 {
  return 200;
}

Great 1 . 好极了1

How can I make a header guard for this type of file? 如何为此类文件设置标题保护? Without guards, if two different consumers of the header file both requested the same VALUE , you'd get an error since two identical versions of the return_* function would be generated. 如果没有保护措施,如果头文件的两个不同使用者均请求相同的VALUE ,则将生成错误,因为将生成两个相同版本的return_*函数。

Now a normal header guard like: 现在是普通的标头保护,例如:

#ifndef DUMB_H_
#define DUMB_H_
...
#endif // DUMB_H_

Isn't going to work since it would only effectively include the file once (the #include sequence above would generate the _100 version of the function, but not the _200 version). 是行不通的,因为这将不仅有效包含文件一次(在#include序列上方会产生_100功能的版本,但不是_200版本)。

In principle I would like to generate the name of a macro using token pasting, to check as the guard, like: 原则上,我想使用令牌粘贴来生成宏的名称 ,以进行保护,例如:

#ifndef DUMB_H_ ## VALUE
#define DUMB_H_ ## VALUE
...

But token pasting can't be used like that (outside of macro expansion). 但是令牌粘贴不能那样使用(在宏扩展之外)。

Any there any other options to prevent this file from being included multiple times with the same VALUE , but to still allow the body to be effectively included once for each different VALUE requested? 是否有其他选项可防止此文件使用相同的VALUE多次包含,但仍允许为每个请求的不同VALUE有效地包含该正文一次?


1 Not great in the sense that this is a good pattern or anything like that, but in it that it at least appears to work. 1从某种意义上说这是一个好的模式或类似的东西不是很好 ,但是从某种意义上说,它至少似乎是可行的。

With the explanation in comment 1 and comment 2 , I think the normal process is more like this. 通过注释1注释2中的解释,我认为正常过程更像这样。 I'm going to use a type as the argument, and generate a 'minimum' function for the different types: 我将使用类型作为参数,并为不同类型生成一个“最小”函数:

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 */

Consumer code 消费者代码

#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));
}

This does not stop you from trying to instantiate the same function twice in a single TU (translation unit), but the compiler will object if you do that. 这不会阻止您尝试在单个TU(转换单元)中实例化同一函数两次,但是如果您这样做,编译器将反对。 And frankly, letting the compiler do the complaining is simpler than trying to make the C preprocessor spot that you've screwed up and rectify your mistake. 坦率地说,让编译器进行抱怨比尝试使您弄糟的C预处理程序更正错误更简单。

If the C code will be generated by another program, then you need to ensure that the code generator keeps a track of what it has requested and ensure that it doesn't double generate the code. 如果C代码将由另一个程序生成,那么您需要确保代码生成器跟踪其请求的内容,并确保它不会双重生成代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM