在用VC6.0向导生成的头文件中,经常可以看见如下的代码段:
#if !defined(AFX_RESIZABLELAYOUT_H__INCLUDED_)
#define AFX_RESIZABLELAYOUT_H__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
...
#endif // !defined(AFX_RESIZABLELAYOUT_H__INCLUDED_)
对于宏有基本了解的朋友应该都知道,头文件中如下的宏定义,是为了避免同样的头文件在同一个.C文件或者.CPP文件多次包含。
#if !defined(XXX)
#define XXX
#endif
这很好理解,但接下来的一段,尤其是#pragma once的意思,我就不是很清楚了。从MSDN得到pragma once的解释是:
"Specifies that the file will be included (opened) only once by thecompiler when compiling a source code file."
英文注释的大意也是说#pragma once是为了避免文件重复包含。疑惑就此产生了,既然宏"#if !defined"已经有这个作用了,为何还要一个"#pragma once"呢? 我接着在网上搜到了几份答案,但大家的回答都很模糊,于是我想放弃,不再想这个问题,但还是不太甘心,就接着看了看别人的解释。突然间,好像灵犀一点,开窍了。虽然"#if !define"和"#pragma once"都有避免重复包含的功能,但是在实现上还是有区别的。举一例如下:
// Test1.h
#if !define (__TESTONE_H_)
#define __TESTONE_H_
...
#endif
// Test2.h
#pragma once
...
// Test.cpp
#include "Test1.h" // line 1
#include "Test1.h" // line 2
#include "Test2.h" // line 3
#include "Test2.h" // line 4
...
头文件Test1.h中用宏来避免重复,头文件Test2.h中用#pragma once来避免重复。编译Test.cpp,将需要打开Test1.h两次,第一次发现宏__TESTONE_H_没有定义,接着就处理宏定义;第二次打开Test1.h时,发现宏__TESTONE_H_已经定义过了,编译器就会略过宏定义部分,知道处理完Test1.h末尾的#endif。
而由于头文件Test2.h使用#pragma once来避免重复定义的,在编译Test.cpp的过程中,Test2.h只会被打开一次,也就是处理到第3行的时候。因为Test2.h用的是#pragma once,所以在处理完第3行后,编译器已经知道包含了一次Test2.h,在它(编译器)处理第4行代码时,发现Test2.h已经包含过了,忽略掉第4行代码,也就不需要再次打开Test2.h进行判断了。
总结一下,除了#pragma once是微软编译器所特有的之外,用宏和#pragma once的办法来避免重复包含头文件,主要区别在于宏处理的方法会多次打开同一头文件,而#pragma once则不会重复打开,从而#pragma once能够更快速。
分享到:
相关推荐
#ifdef,#else,#endif和#ifndef的用法
#ifdef,#else,#endif,#if用法详解
C语言之详解#ifdef等宏及妙用C语言之详解#ifdef等宏及妙用C语言之详解#ifdef等宏及妙用
描述了在C语言中的#ifdef等宏及妙用
#ifdef __cplusplus } #endif 这样的代码到底是什么意思呢?首先,__cplusplus 是cpp 中的自定义宏,那么定义了这 个宏的话表示这是一段cpp 的代码,也就是说,上面的代码的含义是:如果这是一段cpp 的 代码,那么...
C语言之详解#ifdef等宏 C语言之详解#ifdef等宏 C语言之详解#ifdef等宏
#ifdef_#else_#endif_#if_#ifndef的用法.txt
#ifdef __cplusplus深度剖析
最近在看Linux底层代码,发现好多代码里有#define #ifdef #endif,找了个介绍详细的文章,供大家参考!
#ifndef <标识> ,每个头文件的这个“标识”都应该是唯一的。标识的命名规则一般是头文件名全大写。
#ifdef _DEBUG #pragma comment(lib,"libcurld.lib") #else #pragma comment(lib,"libcurl.lib") #endif #pragma comment ( lib, "ws2_32.lib" ) #pragma comment ( lib, "winmm.lib" ) #pragma comment ( lib, ...
这个压缩包里包含VS2022编译好的库文件和dll文件。 include 头文件 lib x64库文件 bin dll文件,hiredis.dll拷入你的程序release文件夹,hiredisd.dll拷入你的程序debug文件夹,DBGHELP.DLL拷入release,debug两个...
2、包含以下预编译指令: #ifdef _DEBUG #ifndef _WIN64 #pragma comment(lib, "zlog_vc100x86.debug.lib") #else #pragma comment(lib, "zlog_vc100x64.debug.lib") #endif #else #ifndef _WIN64 #pragma comment...
vc每次编译时,自动递增版本号信息,vs2005下试验过。 环境 需要在本机安装TortoiseSVN 第一步 在项目的.rc文件中搜索VS_VERSION_INFO VERSIONINFO 按照下面例子更改 VS_VERSION_INFO VERSIONINFO #ifdef _AUTO_...
smartifdef Smart ifdef是sublimetext 3插件,用于在C / C ++源代码中突出显示#ifdef安装使用包控制用法转到首选项->程序包设置-> smartifdef->设置以设置项目的C / C ++宏。 未定义的宏代码将突出显示。 在命令面板...
PC-Lint报错详解(中文版) 难得的中文版本 -1―未关闭注释 (位置) ...检测出一个内部的限制,有关#if的嵌套层次 (包括 #ifdef和#ifndef)。 -5-太多的#endif 出现一个#endif ,但不是#if 或 #ifdef 或#ifndef.的。
#ifdef PORTA #define PORTA_BIT SET_ADDRESS(PORTA) #endif #ifdef PORTB #define PORTB_BIT SET_ADDRESS(PORTB) #endif #ifdef PORTC #define PORTC_BIT SET_ADDRESS(PORTC) #endif #ifdef PORTD #define ...
esbuild-plugin-ifdef 使用此esbuild插件,您可以在JavaScript和TypeScript中使用//#ifdef注释,因此可以有条件地将代码添加到文件中。安装yarn add esbuild-plugin-ifdef用法这会将//#ifdef注释添加到JavaScript和...
2、将两个文件加入到工程中 3、打开StdAfx.h 输入 #define LogFile 如果要关闭日志功能只需注释改行 4、在theApp中 定义public #ifdef LogFile CLogFile m_LogFile; #endif 5、在应用程序InitInstance中 #ifdef ...