C语言中#pragma的用法及使用解读

 更新时间:2025年10月14日 09:29:12   作者:帅气小胖子  
这篇文章主要介绍了C语言中#pragma的用法及使用解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

一、比较矛盾的点-#pragma到底算不算关键字

有人认为是算,而有人则认为不算。

先看反对派,反对派认为#pragma不算是C关键字的原因也很简单,即神并没有认可,那神是什么喃?即我们熟知的C89,C99,C11等协议。并没有规定或者定义#pragma。

认同派则认为反对派过于迂腐,#pragma是个老伙伴了,它为c语言立过工,它为C语言流过血,就因为协议中没有规定,就认为他不是关键字,这样很不好

二、闲话少说,看#pragma具体用法

pragma具体是指编译器使用的,即这是编译器能够识别的和其他类型的#指令是一致的。我们最常见的#include和#define和undefine是一样的。

2.1.#pragma的作用

#pragma 是 C/C++ 预处理指令之一,用来向编译器传递一些平台相关的编译控制信息。

它的特点是:

  • 编译器相关:不同编译器支持的 #pragma 指令不同
  • 功能多样:可以控制编译器的警告、优化、对齐方式、链接等

语法格式

#pragma 指令名 [参数]

2.2. 常用的#pragma示例

(1)#pragma once—— 防止头文件重复包含

#pragma once
  • 作用:保证头文件只被编译一次
  • 优点:比传统的 #ifndef / #define / #endif 更高效
  • 缺点:不是 C 标准,但是大多数现代编译器(GCC、Clang、MSVC)都支持

(2)#pragma pack—— 控制结构体成员对齐方式

#pragma pack(push, 1)  // 按1字节对齐,并保存当前对齐状态
struct Data {
    char a;
    int  b;
    short c;
};
#pragma pack(pop)      // 恢复之前的对齐状态
  • 用途:在网络协议、文件格式、硬件驱动等需要精确定义内存布局的场景
  • #pragma pack(n) 表示按 n 字节对齐(n 取 1、2、4、8 等)主要参数有push和pop和对齐的数字

(3)#pragma message—— 编译时输出提示信息

c运行,这个就很简单,如果我们可以在代码中的任何地方添加,这样我们就能知道编译到什么地方了

#pragma message("正在编译 main.c...")
  • 作用:在编译过程中输出自定义提示信息
  • 常用于条件编译检查

(4)#pragma warning—— 控制编译器警告

MSVC 编译器

#pragma warning(disable: 4996)  // 禁用 4996 号警告
#pragma warning(once: 4820)     // 仅显示一次 4820 号警告
#pragma warning(error: 164)     // 将 164 号警告视为错误

GCC/Clang 一般用 -W-Werror 等命令行参数,不常用 #pragma warning

(5)#pragma comment—— 链接时加入库或其他信息(MSVC)

#pragma comment(lib, "ws2_32.lib")  // 链接 Winsock 库
#pragma comment(linker, "/subsystem:windows") // 设置子系统类型
  • 仅在 Windows + MSVC 环境有效

(6)#pragma GCC diagnostic—— GCC 特定的警告控制

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
    int x; // 不会产生未使用变量警告
#pragma GCC diagnostic pop
  • 作用:临时禁用 / 开启某些 GCC 警告

2.3. 注意事项

  • 可移植性差#pragma 是编译器扩展,不同编译器支持的指令不同。例如 #pragma once 在 GCC/Clang/MSVC 可用,但在某些老编译器可能不支持。
  • 标准中未定义的 #pragma如果编译器遇到不认识的 #pragma,会忽略该指令,不会报错。
  • 尽量使用标准方法如果有标准方法(如 #ifndef 代替 #pragma once),优先使用标准方法,提高可移植性。

总结

#pragma 示例作用常见编译器支持
#pragma once防止头文件重复包含GCC, Clang, MSVC
#pragma pack控制结构体对齐大多数编译器
#pragma message编译时输出信息大多数编译器
#pragma warning控制警告MSVC
#pragma comment链接设置MSVC
#pragma GCC diagnostic控制 GCC 警告GCC, Clang

✅ 结论:

  • #pragma 是 C 语言中一个强大但平台相关的预处理指令,可以用来控制编译器行为、优化、警告、对齐等。
  • 使用时要注意可移植性,优先考虑标准方法,只在必要时使用特定编译器的 #pragma 扩展。

三、一份不同编译器支持的常用 #pragma 指令对照表

这样在跨平台开发时就能清楚哪些可用哪些不可用。

功能MSVCGCC / ClangKeil (ARMCC)IAR说明
防止头文件重复包含#pragma once#pragma once#pragma once#pragma once非标准,但现代编译器普遍支持;标准做法是 #ifndef/#define/#endif
结构体 / 联合对齐

#pragma pack(push, n)

#pragma pack(pop)

#pragma pack(push, n)

#pragma pack(pop)

#pragma pack(push, n)

#pragma pack(pop)

#pragma pack(push, n)

#pragma pack(pop)

设置结构体成员对齐为 n 字节;n 可取 1/2/4/8/16
编译时消息输出#pragma message("text")#pragma message "text"#pragma message("text")#pragma message="text"在编译输出中显示提示信息
禁用 / 开启警告

#pragma warning(disable: 1234)

#pragma warning(default: 1234)

#pragma GCC diagnostic ignored "-Wxxx"#pragma diag_suppress 1234#pragma diag_suppress=Pe123临时关闭 / 恢复特定警告
警告视为错误#pragma warning(error: 1234)#pragma GCC diagnostic error "-Wxxx"#pragma diag_error 1234#pragma diag_error=Pe123将指定警告当作错误处理
链接选项#pragma comment(lib, "libname.lib")#pragma comment(linker, "/option")无(用 -l/-Wl,option)无(用 --library/ scatter file)无(用链接器选项)向链接器传递参数或添加库
代码段 / 节区控制#pragma section("name")__declspec(allocate("name"))__attribute__((section("name")))__attribute__((section("name")))#pragma location="name"将变量 / 函数放入指定段
优化控制#pragma optimize("", off)#pragma optimize("", on)#pragma GCC push_options#pragma GCC optimize("O0")#pragma GCC pop_options#pragma optimize=none#pragma optimize=none局部关闭 / 开启优化
循环优化#pragma loop(hint_parallel(n))#pragma GCC ivdep提示编译器并行 / 向量化优化
对齐控制__declspec(align(n))__attribute__((aligned(n)))__attribute__((aligned(n)))__attribute__((aligned(n)))指定变量 / 类型对齐
内联控制__forceinline__declspec(noinline)__attribute__((always_inline))__attribute__((noinline))同上同上强制内联 / 禁止内联
中断函数__declspec(naked)无(用 __attribute__((naked)))__attribute__((naked))#pragma interrupt定义无栈帧 / 特殊中断函数

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • C++手撸智能指针的教程分享

    C++手撸智能指针的教程分享

    在前文中小编为大家介绍了C++智能指针的一些使用方法和基本原理,所以本文就来自己动手,从0到1实现一下自己的unique_ptr和shared_ptr吧
    2023-05-05
  • OpenCV图像处理之直方图比较方法详解

    OpenCV图像处理之直方图比较方法详解

    直方图比较是对输入的两张图像进行计算得到直方图H1与H2,归一化到相同的尺度空间,然后可以通过计算H1与H2的之间的距离得到两个直方图的相似程度,进而比较图像本身的相似程度。本文将为大家详细讲讲直方图比较的实现方法,需要的可以参考一下
    2022-09-09
  • C语言中类型捕获(typeof)的使用

    C语言中类型捕获(typeof)的使用

    C语言中typeof是一个编译器扩展,支持泛型宏开发,可避免表达式重复求值,提升代码可读性,本文就来详细的介绍一下C语言中类型捕获(typeof)的使用,感兴趣的可以来了解一下
    2025-09-09
  • C++实现从输入中读取字符串

    C++实现从输入中读取字符串

    这篇文章主要介绍了C++实现从输入中读取字符串的实现思路和具体代码,非常的简单实用,有需要的小伙伴可以参考下
    2016-05-05
  • 使用c++调用windows打印api进行打印的示例代码

    使用c++调用windows打印api进行打印的示例代码

    这篇文章主要介绍了使用c++调用windows打印api进行打印的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • 基于Qt实现电子木鱼小游戏

    基于Qt实现电子木鱼小游戏

    今年最火爆的解压小游戏电子木鱼,现在许多软件都上架了这个小程序。我在网上看了一下基本上都是用py和Java写的,所以我用QT重新写了一下,作为小白练手项目非常适合,快跟随小编一起学习一下吧
    2023-01-01
  • C++函数重载与引用实战案例详解

    C++函数重载与引用实战案例详解

    在C++中允许多个函数同名,只要参数列表不同,借助函数重载,一个函数名可有多种用途,使命名更方便、调用更灵活,这篇文章主要介绍了C++函数重载与引用的相关资料,需要的朋友可以参考下
    2025-08-08
  • C++中友元的实例详解

    C++中友元的实例详解

    这篇文章主要介绍了C++中友元的实例详解的相关资料,希望通过本文大家能掌握友元的使用方法,需要的朋友可以参考下
    2017-09-09
  • C++模板基础之函数模板与类模板实例详解

    C++模板基础之函数模板与类模板实例详解

    C++ 除了支持函数模板,还支持类模板(Class Template),所以下面这篇文章主要给大家介绍了关于C++模板基础之函数模板与类模板的相关资料,需要的朋友可以参考下
    2021-06-06
  • C++中static和const的作用和用法

    C++中static和const的作用和用法

    在C++中,"static"和"const"都是用于修饰变量的关键字,它们具有不同的作用,本文通过代码示例给大家详细的介绍static和const的作用和用法,,需要的朋友可以参考下
    2023-06-06

最新评论