【问题标题】:Is it possible create a "variable" header guard name in C?是否可以在 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 中的内容,我们或许可以提出更好的替代方案。

标签: c header c-preprocessor


【解决方案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】:

    我建议:

    1. 删除myheader.h 中的#include 保护。
    2. 为每个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 文件。

    【讨论】:

      猜你喜欢
      • 2021-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-24
      • 2017-10-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多