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”相同
是的,您可以使用不同的定义名称。在您的情况下,LIBRARY、SOMETHING、HEADER_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_H
和 OTHERSUBDIR_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
通常足以确保唯一性)。并且您需要注意某些名称是保留的(例如,以两个下划线开头或下划线后跟大写字母)。
示例:
#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”相同 是的,您可以使用不同的定义名称。在您的情况下,LIBRARY、SOMETHING、HEADER_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_H
和 OTHERSUBDIR_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
通常足以确保唯一性)。并且您需要注意某些名称是保留的(例如,以两个下划线开头或下划线后跟大写字母)。