本篇随笔为转载,原贴地址:#pragma once与#ifndef解析

为了避免同一个文件被include多次,C/C++中有两种方式,一种是#ifndef方式,一种是#pragma once方式。在能够支持这两种方式的编译器上,二者并没有太大的区别,但是两者仍然还是有一些细微的区别。
    方式一:

#ifndef __SOMEFILE_H__
    #define __SOMEFILE_H__
    ... ... // 声明、定义语句
    #endif

方式二:

#pragma once
    ... ... // 声明、定义语句

#ifndef的方式受C/C++语言标准支持。它不光可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件(或者代码片段)不会被不小心同时包含。
    当然,缺点就是如果不同头文件中的宏名不小心“撞车”,可能就会导致你看到头文件明明存在,编译器却硬说找不到声明的状况——这种情况有时非常让人抓狂。
    由于编译器每次都需要打开头文件才能判定是否有重复定义,因此在编译大型项目时,ifndef会使得编译时间相对较长,因此一些编译器逐渐开始支持#pragma once的方式。

#pragma once一般由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。你无法对一个头文件中的一段代码作pragma once声明,而只能针对文件。
    其好处是,你不必再费劲想个宏名了,当然也就不会出现宏名碰撞引发的奇怪问题。大型项目的编译速度也因此提高了一些。
    对应的缺点就是如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含。当然,相比宏名碰撞引发的“找不到声明”的问题,这种重复包含很容易被发现并修正。

#pragma once方式产生于#ifndef之后,因此很多人可能甚至没有听说过。目前看来#ifndef更受到推崇。因为#ifndef受C/C++语言标准的支持,不受编译器的任何限制;而#pragma once方式却不受一些较老版本的编译器支持,一些支持了的编译器又打算去掉它,所以它的兼容性可能不够好。一般而言,当程序员听到这样的话,都会选择#ifndef方式,为了努力使得自己的代码“存活”时间更久,通常宁愿降低一些编译性能,这是程序员的个性,当然这是题外话啦。

还看到一种用法是把两者放在一起的:

#pragma once
    #ifndef __SOMEFILE_H__
    #define __SOMEFILE_H__
    ... ... // 声明、定义语句
    #endif

看起来似乎是想兼有两者的优点。不过只要使用了#ifndef就会有宏名冲突的危险,也无法避免不支持#pragma once的编译器报错,所以混用两种方法似乎不能带来更多的好处,倒是会让一些不熟悉的人感到困惑。

选择哪种方式,应该在了解两种方式的情况下,视具体情况而定。只要有一个合理的约定来避开缺点,我认为哪种方式都是可以接受的。而这个已经不是标准或者编译器的责任了,应当由程序员自己或者小范围内的开发规范来搞定。

btw:我看到GNU的一些讨论似乎是打算在GCC 3.4(及其以后?)的版本取消对#pragma once的支持。不过事实上,我手上的GCC 3.4.2和GCC 4.1.1仍然支持#pragma once,甚至没有deprecation warning,倒是GCC2.95会对#pragma once提出warning。
    VC6及其以后版本亦提供对#pragma once方式的支持,这一特性应该基本稳定下来了。

【转载】#pragma once与#ifndef的更多相关文章

  1. #pragma once 与 #ifndef 解析(转载)

    正在入门驱动编程,遇到一个小问题,如下详细解释. 原文链接:#pragma once 与 #ifndef 解析 http://www.cnblogs.com/hokyhu/archive/2009/0 ...

  2. #pragma once vs #ifndef

    最后编辑: 2019-11-20 #pragma once 是一个非标准但被广泛支持的预处理符号, 其主要作用是防止文件重复引入问题. 在头文件中,可以定义 #pragma once 或者 #ifnd ...

  3. C++ pragma once 与 ifndef 用法区别

    #pragma once 与 #ifndef 的作用 (1)在C/C++中,在使用预编译指令#include的时候,为了防止重复引用造成二义性. (2)在能够支持这两种方式的编译器上,二者并没有太大的 ...

  4. #pragma once与#ifndef #define ...#endif的区别

    1. #pragma once用来防止某个头文件被多次include: #ifndef,#define,#endif用来防止某个宏被多次定义.   2. #pragma once是编译相关,就是说这个 ...

  5. #pragma once与 #ifndef的区别

      为了避免同一个文件被include多次 1   #ifndef方式2   #pragma once方式 在能够支持这两种方式的编译器上,二者并没有太大的区别,但是两者仍然还是有一些细微的区别.   ...

  6. [Windows编程] #pragma once 和#ifndef ... #define ... #endif 比较

    C++中防止头文件被多次include 的常见方式有: 1) 用#ifndef ...  #define ... #endif  宏 #ifndef __MYHEADER_H__#define __M ...

  7. pragma once与#ifndef的作用有什么区别

    #pragma once 这是一个比较常用的指令,只要在头文件的最开始加入这条指令就能够保证头文件被编译一次 #pragma once用来防止某个头文件被多次include,#ifndef,#defi ...

  8. #pragma once 与 #ifndef 解析

    转自:http://www.cnblogs.com/hokyhu/archive/2009/03/30/1425604.html 为了避免同一个文件被include多次,C/C++中有两种方式,一种是 ...

  9. C/C++中宏定义#pragma once与 #ifndef的区别

    为了避免同一个文件被include多次,我们可以通过以下两种方式来进行宏定义: 1. #ifndef方式2. #pragma once方式 在能够支持这两种方式的编译器上,二者并没有太大的区别,但是两 ...

随机推荐

  1. iOS源码学习总结框架

    1.ARChromeActivity: 用于在Google Chrome中打开网址的UIActivity子类. 2.KINWebBrowser: 它使用iOS 8的 WKWebView API编写,同 ...

  2. Golang的一个CLI框架

    因为机缘巧合,因为希望能在VPS中使用百度网盘,了解到了一个开源的项目BaiduPCS-Go,可以用来直接存取访问百度网盘,做的相当不错 而且看ISSUES,作者可能还是个学生,很强的样子.稍微看了下 ...

  3. python学习之数据类型(int,bool,str)

    第三章 数据类型 3.1 Python基本数据类型 类型 含义 描述 int 整数 主要用来进⾏数学运算 str 字符串 可以保存少量数据并进⾏相应的操作 bool 布尔值 判断真假,True,Fal ...

  4. Ciso三层交换 上vlan间互通, 端口映射到vlan

    路由器2911配置: !hostname router interface GigabitEthernet0/0 ip address 10.0.0.2 255.0.0.0 ip nat outsid ...

  5. 【计算机视觉】【神经网络与深度学习】论文阅读笔记:You Only Look Once: Unified, Real-Time Object Detection

    尊重原创,转载请注明:http://blog.csdn.net/tangwei2014 这是继RCNN,fast-RCNN 和 faster-RCNN之后,rbg(Ross Girshick)大神挂名 ...

  6. Array of Doubled Pairs

    Given an array of integers A with even length, return true if and only if it is possible to reorder ...

  7. [转帖]MySQL5.7.20编译安装

    MySQL5.7.20编译安装 尝试一下 想着 我在arm上面最终安装失败了. https://www.cnblogs.com/shengdimaya/p/8027507.html 1:官网下载sou ...

  8. 【案例分享】使用ActiveReports报表工具,在.NET MVC模式下动态创建报表

    提起报表,大家会觉得即熟悉又陌生,好像常常在工作中使用,又似乎无法准确描述报表.今天我们来一起了解一下什么是报表,报表的结构.构成元素,以及为什么需要报表. 什么是报表 简单的说:报表就是通过表格.图 ...

  9. 关于前端JS判断字符串是否包含另外一个字符串的方法总结

    RegExp 对象方法 test() var str = "abcd"; var reg = RegExp(/d/); console.log(reg.test(str)); // ...

  10. 【模板】SPFA(不完全详解)

    一种最短路求法(个人觉得比DIJKSTRA好用) 用于有向图. 大概思路:从根节点开始,枚举每一个点,同时更新他们所联通的点的最短路径,如果路径被更新,则把这个点入队,一直重复这个操作直到队伍为空为止 ...