#pragma 一次位置:在 #include 之前或之后

#pragma once position: before or after #include's

本文关键字:#include 或之后 位置 一次 #pragma      更新时间:2023-10-16

在现有代码中我看到#pragma once在标题#include S

之后使用
//Some_Header.h
#include "header1.h"
#include "header2.h"
#pragma once
//implementations

而不是

//Some_Header.h
#pragma once
#include "header1.h"
#include "header2.h"
//implementations

我认为它总是需要像第二个示例一样,在定义#pragma once的位置是否有意

编辑

我知道#pragma once不是标准的一部分,包括后卫是我的问题。

#pragma once应该放置在包括任何标头之前。#Pragma指令的论点是宏观扩展的主题。因此,随附的标头的内容可以改变巴格马的行为:

// whatever.hpp
...
#define once lol_no
// your_header.hpp
#include "whatever.hpp"
#pragma once // warning C4068: unknown pragma

在这个问题上实际上没有一个完整的答案,涵盖了3个编译器,所以这是我在更完整的答案中尝试。

摘要

  • tl; dr:如果您关心可移植性,请将其放在任何可能与之冲突的#include#define语句之前(例如将其放在标题中(。
  • 得到所有主要编译器的支持(" X86_64编译器以及英特尔和嵌入式编译器(
  • 放置通常只要到达预处理器(例如,不被#if -Branch阻止(
  • 不同的编译器是是否应该是首先,而不记录如果不是。。
  • 大多数编译器已经检测到的是包括后卫并将其视为pragma once,因此好处在很大程度上只是没有创建独特的后卫名称。

以下是一个快速的,摘要的指南:

的编译器文档
编译器 支持 文档
clang 支持 兼容GNU。未记录,但代码将其显示为普通预处理
GCC 支持 GCC Pragmas
msvc 支持(1( msvc one pragma
英特尔(ICC( 支持(1( 英特尔编译器参考手册 - 支持的PRAGMA
intel(icl( 支持(1( ICL使用MSVC前端
英特尔(ICX( 支持 ICX基于clang
德州仪器 支持(2( 参考手册5.11.23
德州仪器(Clang( 支持 这是一个叉叉,所有主要功能仍然有效
ARMCC 支持(3( #pragma once

#pragma once仅与放置的文件有关。是否包含该文件,对编译器至关重要,并且其位置不重要。因此,除了有条件的预处理器指令(如#if#ifdef#ifndef(排除了#pragma once的行,可以将文件放置在文件中的任何位置。编译器不会解析不排除的代码,如果包含预处理器指令,则没有效果。

尽管可以将#pragma once放置在编译器解析的任何行,但我强烈建议遵循共同的练习,并将#pragma once放在标题文件开始时。

另外,正如提到的 @user7860670,#pragma指令的参数是MSVC编译器的宏扩展。但是GCC和Clang都不支持它:

  • MSVC的示例
  • GCC的示例
  • clang的示例