繁体   English   中英

C ++ #ifndef包含文件,为什么所有大写文件都用于头文件?

[英]C++ #ifndef for include files, why is all caps used for the header file?

我想知道为什么#ifndef指令之后的名字总是全部大写并且似乎与实际头文件的名称不匹配? 这有什么规则? 我一直在寻找网络,但我没有找到任何解释。 如果我的头文件名为myheader.h,那么可以使用:

#ifndef MYHEADER

如果是这样,为什么? 规则是什么?

这些是预处理程序符号,没有这样的规则。 (只要它们与标题中的#defines匹配)

但是,惯例是对预处理程序符号使用全大写。

没有“规则”,只有惯例。 第一个也是最常用的约定是所有预编译宏都是大写的,所以标题保护也应该都是大写的。

至于宏名称,我使用的(以及我看到的大多数代码使用的)只是标题的名称(如上所述,转为全部大写),包括扩展名,用下划线替换点,然后是_INCLUDED

#ifndef MYHEADER_HPP_INCLUDED
#define MYHEADER_HPP_INCLUDED
// ...
#endif

请注意,许多前缀此类标识符带有下划线或双下划线,但这不是一种好的做法,因为标准指定标识符开头(或包含)双下划线,以及以单个下划线后跟大写字母开头的标识符保留给编译器/所有范围内特定于库的东西(例如VC ++中的__declspec或标准头中使用的宏); 以单个下划线开头的所有其他标识符都保留在全局范围内。 因此,不应使用此类标识符来避免冲突。

这个东西更多信息在这里

它不需要全部大写。 这只是常见的惯例。 我经常使用像#ifndef MYHEADER_H_INCLUDED这样的东西。

谷歌为包括警卫找到了实际上的东西。

关于全部大写:宏是一种全局大写的惯例 原因是宏是由预处理器处理的,这是一个神秘的文本处理工具,对C ++一无所知,最好不要使用常见的标识符,以免它遍及它们,造成一大堆混乱。

我们的想法是确保您的头文件在构建期间只读取一次。 实现这个的成语是结构:

   #ifndef _SOME_UNIQUE_NAME
   #define _SOME_UNIQUE_NAME
   /* The actual header code */
   #endif

这意味着您应该选择一个您非常确定将是唯一的名称,并且该名称是#ifndef的有效标识符。 您还应确保标识符未在实际代码中使用或与变量或其他内容混淆。 具有大写标记清楚地标记了成语。 除此之外,仅仅是惯例而不是决定选择的语言。 Visual Studio的向导生成类似于标识符的GUID。 Sone编译器支持#pragma一次具有相同的效果。

您可以使用任何您想要的名称,但是您希望使其唯一,以便不会在标题之外定义值,因此使用带有大写的标题名称只是一个很好的约定来确保它。

它完全是主观的,除了通常与用于命名预处理器宏的字符集相关的规则之外,没有强制规则。 传统的宏以大写字母定义。 这有助于他们在源代码中脱颖而出。 我倾向于坚持的一个约定是文件名的严格大写版本,句点由下划线和前导和尾随下划线代替。 因此,对于名为DataTableNameMangler.hpp的文件,include guard看起来像:

#ifndef _DATATABLENAMEMANGLER_HPP_
#define _DATATABLENAMEMANGLER_HPP_

...

#endif // _DATATABLENAMEMANGLER_HPP_

虽然我强烈建议使用名称与文件名完全匹配的一致性,但没有很好的理由。 我通常使用一个小类创建者脚本来生成我的初始类。 以下Bash片段给出了一个想法:

#!/bin/bash
INC_GUARD_NAME="_${1^^*}_HPP_"
echo "#ifndef $INC_GUARD_NAME"
echo "#ifndef $INC_GUARD_NAME"
echo
echo "class $1 {};"
echo
echo "#endif // $INC_GUARD_NAME"

从而:

$ ./makeclass.bash DataTableNameMangler
#ifndef _DATATABLENAMEMANGLER_HPP_
#ifndef _DATATABLENAMEMANGLER_HPP_

class DataTableNameMangler {};

#endif // _DATATABLENAMEMANGLER_HPP_

这自然只是一个非常基本的例子。 重要的是,请记住将注释放在最后一行的警卫名称之前。 #endif没有参数,所以宏将被传递给C ++编译器,如果它没有被注释,它会抱怨它。

暂无
暂无

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

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