C/C++ Pragma Once 使用详解

概述

为了防止头文件的重复引用造成二义性

详细说明

防止重复引用的两种方法

使用 #ifndef 指令,防止代码块重复引用
#ifndef _CODE_BLOCK
#define _CODE_BLOCK

// 这里是避免重复的代码

#endif
使用 #Pragma Once 指令,在想要保护的文件开头
#pragma once

pragma once 的底层实现

#pragma once 是 C 和 C++ 编程语言中的预处理指令,预处理器是编译器的一个组成部分,它在编译过程的最初阶段处理源代码。

当预处理器遇到 #pragma 指令时,它会执行特殊的操作,具体取决于跟在后面的文本。例如:#pragma once,#pragma pack 等。当遇到 #pragma once 时候,通常会做以下几件事:

  1. 预处理器将在内部维护一个列表,记录已经经过处理的头文件。每当遇到 #pragma once ,预处理器都会检查这个列表。
  2. 如果头文件已经在列表中,预处理器会跳过这个头文件,不再处理它。这就防止了同一个头文件在单次编译中被重复包含。
  3. 如果头文件不在列表中,预处理器就会将其加入列表,然后正常处理这个头文件。

需要注意的是,#pragma once 并不是标准 C++ 的一部分,尽管大多数现代 C++ 编译器都支持它。因此,其具体行为可能因编译器不同而有差异。在一些情况下可能会有问题,比如在文件系统链接(软链接、硬链接)或者网络文件系统等复杂场景下,编译器可能无法正确识别文件的唯一性,从而导致 #pragma once 不能正常工作。在一般情况下,使用传统的头文件保护宏(header guard)是更安全更标准的做法:

#ifndef _HEADER_FILE_H
#define _HEADER_FILE_H

// header file content.

#endif

#pragma once 和 #ifndef 的区别

  • 编译器差异:
  • 文件系统差异:在某些文件系统中,同一文件可能有多个有效路径,这可能导致编译器错误的认为同一文件为不同文件。#pragma once 是通过文件路径来判断文件是否被包含。#ifndef 不受此影响,它是通过宏名称来判断的。
  • 代码可读性:#pragma once 比 #ifndef 更简洁,这会使代码更易于阅读和理解。然而,这也可能会使得一些复杂条件的编译场景更难处理,#ifndef 提供了更多的灵活性。
  • 性能:某些情况下,#pragma once 比 #ifndef 更快,因为编译器可以立即知道一个文件是否已经被包含,而不需要扫描整个文件。但是这个性能优势并不显著,特别是对于一些小的项目。

你可能感兴趣的:(c语言,c++)