在C/C++中,为了避免同一个文件被include多次,有两种方式:一种是#ifndef方式,一种是#pragma once方式(在头文件的最开始加入)。
#ifndef SOME_UNIQUE_NAME_HERE
#define SOME_UNIQUE_NAME_HERE
// contents of the header
...
#endif // SOME_UNIQUE_NAME_HERE
#pragma once
// contents of the header
...
#ifndef的是方式是受C/C++语言标准支持。#ifndef方式依赖于宏名不能冲突。它不光可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件不会被不小心同时包含。缺点是如果不同头文件中的宏名不小心”碰撞”,可能就会导致你看到头文件明明存在,编译器却硬说找不到声明的状况。由于编译器每次都需要打开头文件才能判定是否有重复定义,因此在编译大型项目时,#ifndef会使得编译时间相对较长,因此一些编译器逐渐开始支持#pragma once的方式。
#pragma once一般由编译器提供保证:同一个文件不会被包含多次。这里所说的”同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。无法对一个头文件中的一段代码作#pragma once声明,而只能针对文件。此方式不会出现宏名碰撞引发的奇怪问题,大型项目的编译速度也因此提供了一些。缺点是如果某个头文件有多份拷贝,此方法不能保证它们不被重复包含。在C/C++中,#pragma once是一个非标准但是被广泛支持的方式。
#pragma once方式产生于#ifndef之后。#ifndef方式受C/C++语言标准的支持,不受编译器的任何限制;而#pragma once方式有些编译器不支持(较老编译器不支持,如GCC 3.4版本之前不支持#pragmaonce),兼容性不够好。#ifndef可以针对一个文件中的部分代码,而#pragma once只能针对整个文件。
#pragma once is very well supported across compilers but not actually part of the standard. The preprocessor may be a little faster with it as it is more simple to understand your exact intent. To speed up compile time more just forward declare instead of including in .h files when you can.
The use of #pragma once can reduce build times as the compiler will not open and read the file after the first #include of the file in the translation unit. This is referred to as multiple-include optimization. It has an effect similar to the #include guard idiom, which uses preprocessor macro definitions to prevent multiple inclusion of the contents of the file. This also helps to prevent violations of the one definition rule----the requirement that all templates,types, functions, and objects have no more than one definition in your code.
#pragma once is a non-standard, but widely supported, feature of C++ compilers. The concept is simple: any file containing #pragma once will only actually be included once, even if the programmer includes it multiple times.