对于文件名a.h ...我一直使用
#ifndef A_H
#define A_H
#endif
但现在我在教程
中看到了#ifndef __A_H_INCLUDED__
#define __A_H_INCLUDED__
#endif
以及
#ifndef _A_H_INCLUDED
#define _A_H_INCLUDED
#endif
所以我想知道发生了什么......从来没有版本的C ++发生了变化,还是这个编译器依赖?
我使用MinGw(gnu gcc g ++)和msvc ...
修改
如果对于为什么要问这个问题感到困惑,我相信这对初学者来说很困惑。例如,对于名为a.h的文件,我们不说
#ifndef a.h
#define a.h
甚至
#ifndef A_H
#define A_H a.h
这对我有意义。
相反,我们说A_H ......或上面的变体之一。因此,我认为不只是任何语法都可以。我总是认为它必须是大写字母的文件名,并且句号必须用_替换。这就是我多年来一直在教它的方式。不,我看到像_INCLUDED这样的单词......这些单词显然不是a.h文件名的一部分......这很令人困惑......编译器如何协调 A_H_INCLUDED 是指a.h?我不明白为什么这会被投票,我认为这很令人困惑。此外,有人指出其中一些变体不符合标准,因此我认为这是一个有效的问题,不应该被投票。
或者#define A_H是否将头文件中的所有代码转储到A_H宏中?但我认为定义以新行字符结束......在这种情况下,我们定义A_H没有值。在这种情况下,A_H只是一个没有价值的名称,问题仍然是当你使用像 A_H_DINGDONG 那样的时髦空marco变量时编译器如何知道你正在谈论文件a.h?
答案 0 :(得分:1)
#ifndef
,#define
和#endif
是重要的语法部分。您使用的命名约定取决于您。
答案 1 :(得分:1)
这些只是变量名等名称。
保留双下划线名称,严格来说#define __A_H_INCLUDED__
是未定义的行为,下划线+大写字母shouldn't be used either。
您只是想避免命名与其他代码和标准的冲突,并且使用文件名通常可以确保。
答案 2 :(得分:1)
语言没有相关变化。包含保护中使用的标识符只是一个标识符。实际上整个包含保护机制并不是由语言定义的;它只是一个惯例。
问题是,以两个下划线或一个下划线和大写字母开头的标识符将保留给实现。这意味着如果您在代码中使用名称__FOO_H__
,那么编译器已经为其内部目的预先定义了它,并且您的代码可能会以某种不确定的方式中断。
告诉你写的教程:
#ifndef __A_H_INCLUDED__
#define __A_H_INCLUDED__
#endif
给你很差的建议。
还有一个细微之处:以E
开头的宏名称和一个数字,或E
和一个大写字母,保留在<errno.h>
/ <cerror>
标题中使用。因此,如果您的头文件被称为earth.h
并且您写了:
#ifndef EARTH_H
#define EARTH_H
#endif
然后您原则上与EARTH_H
错误号冲突。
这不太可能发生,_H
后缀几乎肯定足以阻止它,但我用来完全避免它的惯例是:
#ifndef H_EARTH
#define H_EARTH
#endif
你建议:
#define a.h
宏名称必须是单个标识符。这实际上定义了值为a
的宏.h
。
#define A_H a.h
由于宏仅使用#ifndef
进行测试,因此它的价值并不重要,只是它是否已定义。
答案 3 :(得分:0)
归结为个人/组织偏好,尽管有一些约定。一般来说,只要它没有在其他任何地方使用,它并不重要。
一些例子:
A_H
:看起来类似于您在代码中使用的常量。A_H_
:会更好,因为你不可能在最后看到一个带有下划线的常量。_A_H_INCLUDED
:乍一看,这个看起来更好,因为它在外观上与私有文件范围变量相似。 但这是一个问题,因为下划线+大写字母是保留的,所以这不是一个合适的宏。A_H_INCLUDED
:没有领先的下划线,明确的目的,不会与您计划中的任何其他内容发生冲突。__A_H_INCLUDED__
:保留双下划线;不要使用。此外,它不是标准的一部分,但#PRAGMA ONCE
得到广泛支持并完成同样的事情而无需担心命名约定。
答案 4 :(得分:0)
#define A_H
与文件a.h
没有任何关联。
在dir/filename.h
内,你可以:
#ifndef WHATEVER_NOT_DEFINED_HENCE_HAVE_DIR_FILENAME_H_IS_GOOD_
#define WHATEVER_NOT_DEFINED_HENCE_HAVE_DIR_FILENAME_H_IS_GOOD_
#endif
但您无法使用此
#define WHATEVER_HAS_DOUBLE_UNDERSCORE_LIKE_THIS_IS_BAD__
#define __OR_LIKE_THIS_IS_BAD
#define OR_LIKE__THIS_IS_BAD
并且你不能以下划线开头,然后跟这样的大写字符:
#define _LIKE_THIS_IS_BAD