是否可以在 C 中创建“变量”标头保护名称?

Posted

技术标签:

【中文标题】是否可以在 C 中创建“变量”标头保护名称?【英文标题】:Is it possible create a "variable" header guard name in C? 【发布时间】:2015-05-11 16:13:29 【问题描述】:

各位程序员

我是 C 预处理器的新手,最近一直在尝试在 C 中创建一个类似泛型的库(作为练习),我在创建标头保护时遇到了一个小问题。

所有预处理器宏都已设置好,因此我可以像这样包含和使用我的标头:

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

但是当我需要在多个文件中包含标题时,就会出现问题。在这种情况下,通常会应用标头保护,但由于标头可以包含一次(每种类型),因此既不能使用通常的构造,也不能使用 #pragma once

然后我的问题是:是否可以创建一个“变量”标头保护以适用于不同的 TYPE 定义?

【问题讨论】:

我猜在这种情况下你将不得不移除标题保护。因为它们的唯一目的是在文件(c、c++ 或任何要编译的文件)中包含一次头文件。 因为您的唯一目的是不止一次地包含标题,那么为什么还要麻烦包含那些编译指示或守卫? 顺便说一句,进入预处理器的好方法.. +1 问题是当我必须 #include 它在多个相同类型的文件中。它给了我多重定义错误 @theadnangondal 说了什么。如果我们能看到 my header.h 中的内容,我们或许可以提出更好的替代方案。 【参考方案1】:

当你想包含来自各种编译单元的头文件时,你可以将头文件分成一个扮演头文件角色的公共部分和一个扮演*.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 */

然后你可以从多个文件中包含这个头文件,但是你必须确保在包含头文件之前只有一个文件定义了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。但是,您必须注意为所有类型实现该功能。 (但链接器会告诉您,您错过了哪些类型。)

【讨论】:

【参考方案2】:

我建议:

    删除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;

【讨论】:

myheader.h 中的守卫仍然不允许包含两次 @theadnangondal,真的。您必须删除 myheader.h 中的 #include 警卫。【参考方案3】:

我认为您正在寻找这样的东西:

#if !defined HEADERGUARD && defined (TYPE==int)
#define HEADERGUARD
<stuff>
#endif

您可能需要 HEADERGUARD_int 和 HEADERGUARD_float,这取决于您在 *.h 文件中所做的事情。更传统的做法是,人们会将它分成两个 *.h 文件。

【讨论】:

以上是关于是否可以在 C 中创建“变量”标头保护名称?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 R 中从参数中获取其名称的函数中创建变量?

在 Github Actions 中创建动态密钥名称

我们可以以编程方式更改在 iPhone 中创建的快捷方式的图标和名称吗

在一个语句中创建一个带有名称的数字向量?

如何防止在 ADAM 中创建重复对象?

是否可以在 C/C++ 中永远不使用标头保护?如果是这样,这种方法有啥优势吗?