简体   繁体   English

我可以/应该在#ifndef之后输入想要输入的内容吗?

[英]Can/should I type whatever I want after #ifndef?

Example: 例:

#ifndef HEADER_h
#define HEADER_h

#endif

Instead of HEADER_h , can I do the following? 除了HEADER_h ,我可以执行以下操作吗?

#ifndef HEADER

or 要么

#ifndef LIBRARY

or 要么

#ifndef SOMETHING

or 要么

#ifndef ANOTHERTHING

etc. 等等

Header guards are just a convention, a "trick", making use of preprocessor conditions. 标头防护只是利用预处理程序条件的一种约定,是一个“技巧”。 In using a header guard you are creating a macro with a name, and checking whether that macro was already defined. 在使用标题保护程序时,您将创建一个具有名称的宏,并检查该宏是否已定义。

There is nothing magical about this macro that binds it to the filename of a header, and as such you can call it whatever you want ( within reason ). 将该宏绑定到标头的文件名没有什么神奇的,因此您可以随意调用它( 在合理范围内 )。

That doesn't mean that you should write #ifndef URGLEBURGLE , though. 但这并不意味着您应该编写#ifndef URGLEBURGLE You want the name to be useful and unique , otherwise there's not much point. 您希望名称有用唯一 ,否则没有太多意义。

Typically something like #ifndef [PROJECTNAME]_[FILENAME]_INCLUDED is a good idea. 通常, #ifndef [PROJECTNAME]_[FILENAME]_INCLUDED是个好主意。

Yes, you can name the include guard symbol whatever you want, but bear in mind that they are supposed to be unique across headers. 是的,您可以根据需要命名包含保护符号,但是请记住,它们在标头中应该是唯一的。 You definitely don't want a header 你绝对不想要标题

// first.h
#ifndef NON_UNIQUE_H
#define NON_UNIQUE_H

void foo();

#endif

and another one 还有一个

// second.h
#ifndef NON_UNIQUE_H
#define NON_UNIQUE_H

void bar();

#endif

When you include both in one translation unit, one will "win" and its declarations will be visible, eg 当您将两者都包含在一个翻译单元中时,一个将“获胜”,并且其声明将可见,例如

// main.cpp

#include "first.h" // now, NON_UNIQUE_H is defined
#include "second.h" // NON_UNIQUE_H already there, doesn't do anything

int main(int, char**)
{
    bar(); // error, won't compile, bar() isn't declared
}

Besides the necessity to circumvent such scenarios, it's best to stick to some convention throughout your project. 除了必要的规避这样的情况下,最好坚持在整个项目的一些惯例。 One classical way of doing it is to convert the header file base name to upper case and append _H . 一种经典的实现方法是将头文件的基本名称转换为大写并附加_H If you have header files with the same base name in different directories, you can include the directory name, eg SUBDIR_FOO_H and OTHERSUBDIR_FOO_H . 如果在不同目录中具有具有相同基本名称的头文件,则可以包含目录名称,例如SUBDIR_FOO_HOTHERSUBDIR_FOO_H But this is up to you. 但这取决于您。

You can use a construction like 您可以使用类似

#if !defined(HEADER) || !defined(LIBRARY)

At your question, you are using 在您的问题上,您正在使用

#ifndef HEADER_h
#define HEADER_h

#endif

It's the same as "#pragma once" And yes, you can use different names of defines. 它与“ #pragma一旦”相同,是的,您可以使用不同的define名称。 In your case, LIBRARY , SOMETHING , HEADER_h - defines, that you can set in code(#define MY_VAR_NAME) or via compiler options(flag -DMY_VAR_NAME). 在您的情况下, LIBRARYSOMETHINGHEADER_h-定义可以在代码(#define MY_VAR_NAME)或通过编译器选项(标志-DMY_VAR_NAME)中进行设置。

Your example is a so-called header guard that allows us to ensure the contents of the header are included only once. 您的示例是所谓的标题保护,使我们能够确保仅将标题的内容包含一次。 However, that is not the only use of #ifndef .You can use #ifndef for conditional compilation as in 但是,这不是#ifndef的唯一用法。您可以使用#ifndef进行条件编译,如下所示

 #ifndef NO_DEBUG
 do_some_debug_stuff();
 #endif

So it is not only for header guards, but in general you have to carefully choose the name of the symbols you are introducing to prevent they are clashing with symbols defined elsewhere. 因此,它不仅用于标题保护,而且通常必须仔细选择要引入的符号的名称,以防止它们与其他地方定义的符号冲突。 It is just that header guards are so common that certain conventions exist (eg using FOLDER_FILENAME_H is usually sufficient to ensure uniqueness). 只是标题保护非常普遍,以至于存在某些约定(例如,使用FOLDER_FILENAME_H通常足以确保唯一性)。 And you need to be aware that certain names are reserved (eg starting with two underscores or underscore followed by capital letter). 您需要知道某些名称是保留的(例如,以两个下划线开头或下划线后跟大写字母)。

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

相关问题 我应该尽可能多地使用 #ifndef Q_MOC_RUN 吗? - Should I use #ifndef Q_MOC_RUN as much a possible? 如何打印在Yacc /野牛中看到的所有内容? - How can I print whatever I see in Yacc/Bison? 我如何处理 TMP 以避免打印任何内容 - how can I handle a TMP to avoid printing whatever 将 void* 转换为任何内容时,我应该使用 static_cast 还是 reinterpret_cast - Should I use static_cast or reinterpret_cast when casting a void* to whatever 链接器错误,即使我用#ifndef阻止它们 - Linker errors even though I prevent them with #ifndef 我可以将指针作为指向类的指针传递,以便我可以使用分配给类中指针的任何内容吗? - Can I pass a pointer as a pointer to a class, so I can use the whatever is assigned to the pointer in the class? 我想知道变量的类型 - I want to know the type of a variable 我想使用Tensorflow C ++ API,但是从源代码构建Tensorflow之后,应该如何在Xcode中链接库? - I want to use Tensorflow C++ API, but after I build Tensorflow from source, how should I link libraries in Xcode? 我写东西后想在consol中有第一行..我怎么能得到? - I want to have first row in consol after i write something.. how can i get? 无论我用作输入,输出全为零 - whatever i use as inputs, outputs are all zeros
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM