浅析pragma once与include guard

来源:互联网 发布:华为liteos 源码下载 编辑:程序博客网 时间:2024/05/18 01:31

控制C/C++头文件编译方法

控制头文件编译一般有两种方法#pragma once 和include guard (即#ifndef,#define,#endif)

#pragma once与#ifndef,#define,#endif

一、#pragma once
  一个比较常用的指令,只要在头文件的最开始加入这条指令就能够保证头文件被编译一次 ,#pragma once是编译相关,不过大部分编译器都有这个定义。
  使用方式:
  #pragma once
  … … // 一些声明语句
#pragma once由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。带来的好处是,不会出现宏名碰撞引发的奇怪问题。对应的缺点就是如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含。当然,相比宏名碰撞引发的“找不到声明”的问题,重复包含更容易被发现并修正。

二、#ifndef,#define,#endif
这个是C++语言相关,这是C++语言中的宏定义,通过宏定义避免文件多次编译。所以在所有支持C++语言的编译器上都是有效的,如果写的程序要跨平台,最好使用这种方式

方式:
  #ifndef SOMEFILE_H
  #define SOMEFILE_H
  … … // 一些声明语句
  #endif

#ifndef的方式依赖于宏名字不能冲突,这不光可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件不会被不小心同时包含。当然,缺点就是如果不同头文件的宏名不小心“撞车”,可能就会导致头文件存在,编译器却找不到声明 。
  

总结:#pragma once 和#ifndef的区别

性能上的区别:
使用#ifndef 的话,编译器每次看到#include这个文件,都需要读入文件,解析代码;而使用#pragma once 编译器不会重复打开文件,大大提高了效率。(不过有些编译器已经对include guard 做了优化,编译速度同样加快了,所以这一项#pragma once优势有限 )
https://en.wikipedia.org/wiki/Pragma_once

编码风格上的区别:
使用#pragma once的代码简洁,重要的是它避免了头文件标号

语意上的区别:
#pragma once是针对文件的,它告诉编译器,本文件只编译一次(根据文件名,路径等信息来保证其唯一性)Include guard是保证其宏定义ifndef define 。。。endif 内的内容不被重复编译

可移植性方面:
#ifndef #define #endif是C++标准里面的一部分,对于任何完好支持c/c++的编译器都能使用。显而易见,可移植性更高。

0 0