简体   繁体   English

取消定义已经包含的标题

[英]Undefine already included header

I want to check a header in my source file and if its already defined, I want to undefine it. 我想检查源文件中的标头,如果它已经定义,我想取消定义它。

Is it possible? 可能吗?

'including' something in c/c++ essentially means: make the preprocessor copy and paste the #include <file> directly into your source code (or better: the preprocessed version of your source code). c / c ++中的“包含”本质上是指:使预处理程序复制#include <file>并将其直接粘贴到您的源代码中(或者更好的是:您的源代码的预处理版本)。

you can not make that copy and paste action undone. 您无法撤消该复制和粘贴操作。 you can however '#undef' stuff introduced by that copy and paste action, but you have to do this for every atom you dislike, you just can't #undef the whole file. 但是,您可以对复制和粘贴操作引入“ #undef”内容,但是必须对每个不喜欢的原子执行此操作,只是不能#undef整个文件。

to check, if a given header was already included, you have check if something from that header file is defined already. 要检查是否已包含给定的标头,则需要检查是否已定义了该标头文件中的某些内容。 most headers contain so called 'guards' which look like 大多数标题包含所谓的“守卫”,看起来像

 #ifndef FOO_H
 #define FOO_H
 /* lots of code */
 #endif

for a file called 'foo.h'. 用于名为“ foo.h”的文件。 you could check for 'FOO_H' like this: 您可以像这样检查“ FOO_H”:

 #ifdef FOO_H
 /* do your magic */
 #endif

example: 例:

 foo.h:
 #ifndef FOO_H
 #define FOO_H
 struct Foo { /* ... * };
 #endif

 bar.h:
 #include "foo.h"
 #ifdef FOO_H
 #undef Foo
 #endif

but that can lead to a lot of headaches if you are not aware of what exactly you are doing. 但这会导致很多头痛,如果您不知道自己到底在做什么。 IF your real problem is, that your compiler complaints about 'already declared stuff' then you are not guarding your header files against multiple inclusion... 如果您的真正问题是,您的编译器抱怨“已经声明的东西”,那么您就无法防止头文件被多重包含...

Do you mean you want to ensure that the header file is included once and only once? 您是说要确保仅一次包含头文件吗? The standard solution to this is using an include guard . 对此的标准解决方案是使用include Guard

Ie surround the contents of your header with 即用您的标题内容

#ifndef MY_HEADER // a unique identifier for each header
#define MY_HEADER

...

#endif

This is guaranteed to work in all platforms. 保证可以在所有平台上使用。 Some compilers also provide a #pragma to achieve the same effect with less hassle, eg in Visual C++ you can add 一些编译器还提供了#pragma ,以减少麻烦,从而达到相同的效果,例如,在Visual C ++中,您可以添加

#pragma once

at the start of your header file. 在头文件的开头。

#undef is the opposite of #define and actually cancels it. #undef#define相反,实际上将其取消。

It's very useful when you need a macro for some task but does not wish to "pollute" the symbol tables 当您需要宏来执行某些任务但又不想“污染”符号表时,此功能非常有用

// referencing FOO is an error (not yet defined)

#define FOO(arg_) ....

FOO(A)
FOO(B)
FOO(C)

#undef FOO

// referencing FOO now is an error (not defined)

There is no way to cancel a #include directive. 无法取消#include指令。

You can't do what you seem to want to do. 您无法做自己想做的事。 If you don't want the header included your choices are 如果您不希望包含标题,则可以选择

don't include it in the first place 不要放在第一位

conditionally include it or not via the prepocessor eg 是否有条件通过前置程序包含它,例如

#ifdef INC_MY_HEADER
#include "myheader.h"
#endif

or assuming the header has header guards just define the header guard before the header is included eg from the commend line -DMY_HEADER or similar 或假设标头具有标头防护,只需在包含标头之前定义标头防护,例如,从命令行-DMY_HEADER或类似名称开始

If the real problem is that you have different headers defining things with the same name then you probably need to look into namespaces so you don't get clashes 如果真正的问题是您使用相同的名称定义了不同的标头,则可能需要查看名称空间,以免发生冲突

You could stop the header being included - the simplest way would be to remove or comment out the #include directive. 您可以停止包含标头-最简单的方法是删除或注释掉#include指令。

You could also pre-define your guards so that the include is inneffective. 您还可以预定义防护,以使包含无效。

foo.h
#ifndef __FOO_H
#define __FOO_H

/* contents of foo.h */

#endif /* __FOO_H */


foo.cpp
#define __FOO_H
#include "foo.h"
/* contents of foo.cpp */

Using this strategy you could use the preprocessor to select whether to pre-define the guards, or even have inner guards within you header. 使用此策略,您可以使用预处理器来选择是预定义防护,还是在标头中甚至包含内部防护。

If you really need only to have part of the file included, it would be better to split the file into two. 如果您确实只需要包含文件的一部分,则最好将文件分成两部分。

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

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