#pragma 一次位置:在 #include 之前或之后
#pragma once position: before or after #include's
在现有代码中我看到#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的示例
相关文章:
- 在 OpenCV 的 namedWindow 之前或之后初始化 Tesseract
- macOS 致命错误:sys/_types/_int8_t.h:没有此类文件或目录 #include < sys/_types/_int8_t.h>
- /usr/include/c++/7/cstdlib:75:15:致命错误:stdlib.h:没有这样的文件或目录 #i
- 使用 #include 将大量重复代码放入单独的文件中是否可以和/或正常?
- 【MacOSX 10.15.1】使用 odb 生成数据库,致命错误:wchar.h:没有这样的文件或目录 #include < wchar.h>
- #pragma 一次位置:在 #include 之前或之后
- 快速报告 - 在显示准备报告之前或之后清除最后报告
- Winsockets - 身体之前和/或之后的奇怪字符
- 是在C 静态初始化之前或之后调用dllgetClassObject
- 最佳做法:src/include 或 src 文件夹旁边的 include 文件夹
- 是在默认构造函数之前或之后调用的初始化列表
- EOF 位:读取失败之前或之后
- 类型之前或之后的常量
- 变量名应该在名词之前或之后有形容词吗
- 为什么必须在 Linux 系统上"installed" uuid.h 才能构建许多C++程序,而不仅仅是放入 include 或 lib 文件夹
- 在计算函数返回值之前或之后是否销毁了局部变量
- 在方法名称之前或之后放置常量、静态和虚拟
- 在C++中,构造函数是在对象创建之前或之后调用的
- 在自动销毁变量之前或之后创建的c++返回值
- 在C++中添加到集合之前或之后