您的位置:首页 > 其它

#pragma once和#ifndef的区别

2016-06-05 10:57 302 查看
转载自“百度百科”#pragma once 和 #ifndef的区别
#pragma once和#ifdef都是可以避免同一个文件被include多次。在能够支持这两种方式的编译器上,二者并没有太大的区别,但是两者仍然还是有一些细微的区别。
1. #pragma once方式
这个是编译器相关,就是说在这个编译系统上能用,但是在其他编译系统,不一定行,也就是说移植型差。不过现在基本上已经是每个编译器都有这个定义了。编译器提供保证,同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。于是不必再费劲想个宏名了,当然也就可以避免宏的名字冲突问题了。缺点:如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含。
// 看看VC自带的Stdarg.h头文件中是怎么使用#pragma once的
// 毕竟微软的东西权威嘛 - -||
//

#if     _MSC_VER > 1000
#pragma once
#endif

#ifndef _INC_STDARG
#define _INC_STDARG

#include <vadefs.h>

#define va_start _crt_va_start
#define va_arg _crt_va_arg
#define va_end _crt_va_end

#endif  /* _INC_STDARG */
此时只需要注意以下三行代码:
#if     _MSC_VER > 1000
#pragma once
#endif
其中_MSC_VER宏是由微软编译器指定的,表示编译器的版本号。可以看到,在宏_MSC_VER的值小于1000(VC5.0)时,它对 #pragma once 是不支持的。
2. #ifndef方式
这个是C++语言相关,这是C++语言中的宏定义,通过宏定义避免文件多次编译。所以在所有支持C++语言的编译器上都是有效的。如果写的程序要跨平台,最好使用这种方式。#ifndef由语言支持,移植性好。它依赖于宏名字不能冲突,这不光可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件不会被不小心同时包含。另外,为了保证不同头文件中的宏名不冲突,故采取类似于_ABC_H_的取名方式。其中,abc.h为当前头文件名。缺点:如果不同头文件的宏名不小心“撞车”,可能就会导致头文件明明存在,编译器却硬说找不到声明的状况。但这个缺点恰恰是我们可以利用的优点,#ifndef方式可以通过前面介绍的特殊的宏的取名方式来避免名称冲突问题,于是其缺点也就不复存在了,进而#ifndef方式就更常用了。
还看Stdarg.h头文件,这个头文件里面不仅使用了#pragma once方式而且使用了#ifndef方式来保证该头文件不被多次include.
#ifndef _INC_STDARG
#define _INC_STDARG

// …………

#endif  /* _INC_STDARG */

3. 总结
·性能上的区别
使用 #ifndef 的话,编译器每次看到#include这个文件都需要读入文件,解析代码;而使用#pragma once 编译器根本不会重复打开文件, 大大提高了效率。
·编码风格上的区别
使用#pragma once的代码简洁,重要的是它避免了头文件标号(如_myheader_h_)的 重定义或者 #endif 包含范围错误的情况。
·语意上的区别
#pragma once是针对文件的,它告诉编译器,本文件只编译一次。
#ifndef…#define…#endif 只是针对文件中的某一个标号而言的,它能防止三个指令间包含的内容的重复性处理。就这一点而言,后者更灵活。可移植性方面
#pragma once是微软的开发工具中所使用的,如 msvc 等工具可以完好的支持;
#ifndef #define #endif是C++标准里面的一部分,对于任何完好支持c/c++的编译器都能使用。显而易见,后者的可移植性更高。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: