繁体   English   中英

需要澄清#ifndef #define

[英]Need clarification on #ifndef #define

我正在工作的代码具有针对不同类face.cc, face.hh, cell.cc, cell.hh edge.cc edge.hh多个类的头文件和源文件,并且头文件包含这样的内容,

#ifndef cellINCLUDED
#define cellINCLUDED

#ifndef faceINCLUDED
#define faceINCLUDED

我通过http://www.cplusplus.com/forum/articles/10627/进行了查看,并发现编写包含保护的方法是

#ifndef __MYCLASS_H_INCLUDED__
#define __MYCLASS_H_INCLUDED__

因此,在我正在处理的上述代码中,编译器是否会自动理解它正在寻找face.hhcell.hh文件?

更好的问题:是写__CELL_H_INCLUDED__一样cellINCLUDED

 #ifndef __MYCLASS_H_INCLUDED__ #define __MYCLASS_H_INCLUDED__ 

因此,在我正在处理的上述代码中,编译器是否会自动理解它正在寻找face.hh或cell.hh文件?

不,编译器不会自动理解您的意思。

真正发生的是,在编译翻译单元时 ,编译器会保存一个全局定义的MACRO列表。 因此,您正在定义MACRO __MYCLASS_H_INCLUDED__如果尚不存在)。

如果定义了该宏,则实际编译器将不会解析直到#endif为止的#ifndef 因此,您可以测试该MACRO的存在,以确定编译器是否已解析该头文件以将其仅一次包含在转换单元中...这是因为编译器将每个转换单元编译为一个展平文件(合并后)所有#includes

参见https://en.wikipedia.org/wiki/Include_guard

正在写__CELL_H_INCLUDED__一样cellINCLUDED

是的,这是...。某些人偏爱将带下划线的前缀和后缀的MACRO用作包含保护的原因是,因为它们被用作标识符的可能性极低...但是, 下划线可能会与编译器发生冲突 ...

我喜欢这样的东西: CELL_H_INCLUDED

如果使用cellINCLUDED ,则有一天可能会有人将其用作该翻译单元中的标识符

预处理程序定义没有特殊含义。 唯一的要求是它们在模块之间保持唯一,这就是文件名通常是模块一部分的原因。

特别是,防止双重包容的机制并没有“用”这种语言,而只是使用预处理器的机制。

话虽如此,如今每个值得关注的编译器都支持#pragma once ,您可能会对此感到满意。

正如您所引用的链接所说,“编译器没有自己的大脑”-因此,要回答您的问题,不,编译器无法理解涉及到哪些特定文件。 它甚至不了解'__cellINCLUDED'在概念上与特定文件有关。

相反,包含保护只是简单地防止多次重复包含在其打开#ifndef和关闭#endif之间包含的逻辑。 ,作为程序员,告诉编译器不包括代码多次-编译器没有做任何事情“智能”上一把。

是的,这实际上是告诉编译器/解析器,如果它已经被放入程序中,则不要被加载。

该文件应位于.h文件的顶部(底部带有#endif)。

假设您有mainProgram.cpp和Tools.cpp,其中每个文件都加载fileReader.h。 在编译器编译每个 cpp文件时,它将尝试加载fileReader.h。 除非您不告诉它,否则它将两次加载所有fileReader文件。

ifndef =如果未定义

因此,当您使用这些代码(以及.h文件中所有代码之后的#endif)时,您会说:

if not defined: cellINCLUDED
then define: cellINCLUDED with the following code:
[code]
end of code

因此,这样一来,当第二次将代码加载到.h文件中时,它将命中if定义位,并第二次忽略该代码。

这减少了编译时间,也意味着如果您使用的是较旧/较旧的编译器,则不会尝试再次插入代码。

暂无
暂无

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

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