是否可以在 C 中创建一个 "variable" header 守卫名称?
Is it possible create a "variable" header guard name in C?
各位程序员,
我是 C 预处理器的新手,最近一直在尝试在 C 中创建一个 generic-like 库(作为练习),我在创建 [=27= 时遇到了一个小问题] 守卫.
所有预处理器宏都已设置,因此我可以像这样包含和使用我的 header:
#define TYPE int
#include "myheader.h"
#undef TYPE
#define TYPE float
#include "myheader.h"
#undef TYPE
int main(void){
//Do stuff
MyFunc_int();
//More stuff
MyFunc_float();
return 0;
}
但是当我需要在多个文件中包含 header 时,问题就出现了。 Header 守卫通常在这种情况下应用,但由于 header 可以包含一次 - 对于每种类型 - ,通常的结构和 #pragma once
都不能使用。
我的问题是:是否可以创建一个 "variable" header 守卫来处理不同的 TYPE
定义?
我建议:
- 删除
myheader.h
中的 #include
个守卫。
- 为每个
TYPE
创建不同的头文件。
intheader.h:
#pragma once
#define TYPE int
#include "myheader.h"
#undef TYPE
floatheader.h:
#pragma once
#define TYPE float
#include "myheader.h"
#undef TYPE
然后使用:
#include "intheader.h"
#include "floatheader.h"
int main(void){
//Do stuff
MyFunc_int();
//More stuff
MyFunc_float();
return 0;
}
我想你正在寻找这样的东西:
#if !defined HEADERGUARD && defined (TYPE==int)
#define HEADERGUARD
<stuff>
#endif
您可能需要 HEADERGUARD_int 和 HEADERGUARD_float,具体取决于您在 *.h 文件中所做的事情。更传统的做法是,人们会把它分成两个 *.h 文件。
当你想包含来自不同编译单元的 header 时,你可以将 header 分为扮演 header 角色的公共部分和扮演 header 角色的私有部分扮演*.c
文件的角色,例如:
#define M_CONCAT(a, b) a##b
TYPE M_CONCAT(TYPE, _min)(TYPE a, TYPE b);
#ifdef IMPLEMENT
TYPE M_CONCAT(TYPE, _min)(TYPE a, TYPE b)
{
return (a < b) ? a : b;
}
#endif /* IMPLEMENT */
然后你可以从多个文件中包含这个 header,但是你必须确保在包含 header 之前只有一个文件定义了 IMPLEMENT
:
#define IMPLEMENT // only in one file
#define TYPE float
#include "myheader.h"
#undef TYPE
#define TYPE int
#include "myheader.h"
#undef TYPE
这个文件可以是一个单独的编译单元,myheader.c
。但是,您必须注意为所有类型实现该功能。 (但链接器会告诉您,您错过了哪些类型。)
各位程序员,
我是 C 预处理器的新手,最近一直在尝试在 C 中创建一个 generic-like 库(作为练习),我在创建 [=27= 时遇到了一个小问题] 守卫.
所有预处理器宏都已设置,因此我可以像这样包含和使用我的 header:
#define TYPE int
#include "myheader.h"
#undef TYPE
#define TYPE float
#include "myheader.h"
#undef TYPE
int main(void){
//Do stuff
MyFunc_int();
//More stuff
MyFunc_float();
return 0;
}
但是当我需要在多个文件中包含 header 时,问题就出现了。 Header 守卫通常在这种情况下应用,但由于 header 可以包含一次 - 对于每种类型 - ,通常的结构和 #pragma once
都不能使用。
我的问题是:是否可以创建一个 "variable" header 守卫来处理不同的 TYPE
定义?
我建议:
- 删除
myheader.h
中的#include
个守卫。 - 为每个
TYPE
创建不同的头文件。
intheader.h:
#pragma once
#define TYPE int
#include "myheader.h"
#undef TYPE
floatheader.h:
#pragma once
#define TYPE float
#include "myheader.h"
#undef TYPE
然后使用:
#include "intheader.h"
#include "floatheader.h"
int main(void){
//Do stuff
MyFunc_int();
//More stuff
MyFunc_float();
return 0;
}
我想你正在寻找这样的东西:
#if !defined HEADERGUARD && defined (TYPE==int)
#define HEADERGUARD
<stuff>
#endif
您可能需要 HEADERGUARD_int 和 HEADERGUARD_float,具体取决于您在 *.h 文件中所做的事情。更传统的做法是,人们会把它分成两个 *.h 文件。
当你想包含来自不同编译单元的 header 时,你可以将 header 分为扮演 header 角色的公共部分和扮演 header 角色的私有部分扮演*.c
文件的角色,例如:
#define M_CONCAT(a, b) a##b
TYPE M_CONCAT(TYPE, _min)(TYPE a, TYPE b);
#ifdef IMPLEMENT
TYPE M_CONCAT(TYPE, _min)(TYPE a, TYPE b)
{
return (a < b) ? a : b;
}
#endif /* IMPLEMENT */
然后你可以从多个文件中包含这个 header,但是你必须确保在包含 header 之前只有一个文件定义了 IMPLEMENT
:
#define IMPLEMENT // only in one file
#define TYPE float
#include "myheader.h"
#undef TYPE
#define TYPE int
#include "myheader.h"
#undef TYPE
这个文件可以是一个单独的编译单元,myheader.c
。但是,您必须注意为所有类型实现该功能。 (但链接器会告诉您,您错过了哪些类型。)