Can/should 我在#ifndef 后输入我想要的任何内容?

Can/should I type whatever I want after #ifndef?

示例:

#ifndef HEADER_h
#define HEADER_h

#endif

除了 HEADER_h,我可以执行以下操作吗?

#ifndef HEADER

#ifndef LIBRARY

#ifndef SOMETHING

#ifndef ANOTHERTHING

等等

你可以使用像

这样的结构
#if !defined(HEADER) || !defined(LIBRARY)

针对您的问题,您使用的是

#ifndef HEADER_h
#define HEADER_h

#endif

与“#pragma once”相同 是的,您可以使用不同的定义名称。在您的情况下,LIBRARYSOMETHINGHEADER_h - 定义,您可以设置在代码中(#define MY_VAR_NAME) 或通过编译器选项(flag -DMY_VAR_NAME).

是的,您可以随意命名包含保护符号,但请记住它们在 header 中应该是唯一的。你绝对不想要 header

// first.h
#ifndef NON_UNIQUE_H
#define NON_UNIQUE_H

void foo();

#endif

还有一个

// second.h
#ifndef NON_UNIQUE_H
#define NON_UNIQUE_H

void bar();

#endif

当您将两者都包含在一个翻译单元中时,一个将 "win" 并且其声明将可见,例如

// 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
}

除了必须避免此类情况外,最好在整个项目中坚持一些惯例。一种经典的做法是将 header 文件基本名称转换为大写并附加 _H。如果您在不同的目录中有 header 个具有相同基本名称的文件,您可以包括目录名称,例如SUBDIR_FOO_HOTHERSUBDIR_FOO_H。但这取决于你。

Header 守卫只是一个约定,"trick",利用预处理器条件。在使用 header 守卫时,您正在创建一个带有名称的宏,并检查该宏是否已定义。

这个将它绑定到 header 文件名的宏并没有什么神奇之处,因此你可以随意调用它 (within reason)。

但这并不意味着您应该#ifndef URGLEBURGLE。您希望名称有用独特,否则没有太大意义。

通常 #ifndef [PROJECTNAME]_[FILENAME]_INCLUDED 是个好主意。

您的示例是 so-called header 守卫,它使我们能够确保 header 的内容仅包含一次。然而,这不是 #ifndef 的唯一用途。您可以使用 #ifndef 进行条件编译,如

 #ifndef NO_DEBUG
 do_some_debug_stuff();
 #endif

所以它不仅适用于 header 守卫,而且通常你必须仔细选择你要引入的符号的名称,以防止它们与其他地方定义的符号发生冲突。只是 header 守卫是如此普遍以至于存在某些约定(例如,使用 FOLDER_FILENAME_H 通常足以确保唯一性)。并且您需要注意某些名称是保留的(例如,以两个下划线开头或下划线后跟大写字母)。