C 语言中 # 杂注的使用

#pragma在 C 语言中有哪些用途,并举例说明?

210389 次浏览

#pragma once放在头文件的顶部将确保它只包含一次。请注意,#pragma once不是标准的 C99,但大多数现代编译器都支持它。

另一种选择是使用 include 警卫(例如 #ifndef MY_FILE #define MY_FILE ... #endif /* MY_FILE */)

#pragma用于在 C 语言中做一些特定于实现的事情,也就是说,对于当前上下文要务实,而不是在意识形态上固执己见。

我经常使用的是 #pragma pack(1),我试图从嵌入式解决方案的内存空间中挤出更多的空间,使用结构数组,否则最终结果将是8字节对齐。

可惜我们还没有 #dogma,那会很有趣的;)

#pragma是针对特定于机器或特定于操作系统的编译器指令的,也就是说,它告诉编译器执行某些操作、设置某些选项、采取某些操作、覆盖某些默认值等,这些指令可能适用于所有机器和操作系统,也可能不适用于所有操作系统。

有关更多信息,请参见 我不知道

我的最佳建议是查看编译器的文档,因为根据定义,杂注是特定于实现的。例如,在嵌入式项目中,我使用它们来定位不同部分中的代码和数据,或者声明中断处理程序。例如:

#pragma code BANK1
#pragma data BANK2


#pragma INT3 TimerHandler

如果可能的话,我通常会尽量避免使用 # 杂注,因为它们非常依赖于编译器并且不可移植。如果希望以可移植的方式使用它们,则必须使用 #if/#endif对围绕每个杂注。GCC 不鼓励使用杂注,并且实际上只支持其中的一些,以便与其他编译器兼容; GCC 有其他方法来完成其他编译器使用杂注完成的相同工作。

例如,如何在 MSVC 中确保一个结构被紧密打包(即成员之间没有填充) :

#pragma pack(push, 1)
struct PackedStructure
{
char a;
int b;
short c;
};
#pragma pack(pop)
// sizeof(PackedStructure) == 7

在海湾合作委员会你也会这么做:

struct PackedStructure __attribute__((__packed__))
{
char a;
int b;
short c;
};
// sizeof(PackedStructure == 7)

GCC 代码更具可移植性,因为如果您想使用非 GCC 编译器编译它,您所需要做的就是

#define __attribute__(x)

然而,如果想要移植 MSVC 代码,就必须用 #if/#endif对围绕每个杂注。不太好看。

我的感觉是 #pragma是一个指令,如果你想要的代码是位置特定的。如果你想让程序计数器从写入 ISR 的特定地址读取,那么你可以使用 #pragma vector=ADC12_VECTOR在该位置指定 ISR,然后中断轮询名称及其描述

这是一个预处理器指令,可用于打开或关闭某些特性。

它有两种类型 #pragma startup#pragma exit#pragma warn

#pragma startup允许我们指定程序启动时调用的函数。

#pragma exit允许我们指定程序退出时调用的函数。

#pragma warn告诉计算机是否禁止任何警告。

可以使用许多其他 #pragma样式来控制编译器。

#pragma startup是一个指令,用于在 main 函数之前调用函数,并在 main 函数之后调用另一个函数,例如。

#pragma startup func1
#pragma exit func2

在这里,func1main之前运行,func2在之后运行。

注意: 此代码仅在 Turbo-C 编译器中有效。为了在 GCC 中实现这个功能,您可以像下面这样声明 func1func2:

void __attribute__((constructor)) func1();
void __attribute__((destructor)) func2();

上面的所有答案都很好地解释了 #pragma,但我想添加一个小例子

我只是想解释一下 simple OpenMP example,它演示了 #pragma在完成工作时的一些用法

OpenMP briefly是一种用于多平台共享内存的实现 并行程序设计 (然后我们可以说它是 machine-specific或者 operating-system-specific)

让我们来看看这个例子

#include <stdio.h>
#include <omp.h>// compile with: /openmp


int main() {
#pragma omp parallel num_threads(4)
{
int i = omp_get_thread_num();
printf_s("Hello from thread %d\n", i);
}
}

输出是

Hello from thread 0
Hello from thread 1
Hello from thread 2
Hello from thread 3


Note that the order of output can vary on different machines.

现在让我告诉你 #pragma做了什么..。

它告诉操作系统在4个线程上运行一些代码块

这只是一个 many many applications你可以做的小 #pragma

对不起,外面的样品 OpenMP

总而言之,#pragma告诉编译器去做一些事情:

  • #pragma可用于忽略编译器警告。例如,为了让海湾合作委员会对隐函数声明闭嘴,你可以这样写:

    #pragma GCC diagnostic ignored "-Wimplicit-function-declaration"
    

    旧版本的 libportable就是这样做的 随身携带

  • #pragma once写在头文件的顶部时,将导致该头文件被包含一次。一次支持 libportable 支票为杂音。