在C中使用#pragma

107 c pragma

#pragmaC中有哪些用途,有例子?

Ste*_*owe 61

#pragma 用于特定于机器或特定于操作系统的编译器指令,即它告诉编译器执行某些操作,设置一些选项,执行某些操作,覆盖某些默认值等,这些操作可能适用于所有机器并可能不适用于所有机器和操作系统.

有关详细信息,请参阅msdn.

  • "这可能适用于所有机器和操作系统,也可能不适用." - 和同一台机器上的不同编译器.这可能对不同的编译器意味着不同的东西. (11认同)

Sma*_*acL 52

#pragma 用于在C中执行特定于实现的内容,即对于当前上下文而不是意识形态教条是务实的.

我经常使用的是#pragma pack(1)我试图在嵌入式解决方案上挤出更多内存空间的地方,结构数组最终会以8字节对齐方式结束.

可惜我们还没有#dogma.这应该很有趣 ;)

  • 然后我们需要#karma来覆盖(运行)#dogma (47认同)
  • @Pacerier,通常不是.根据jalfs注释,对于32位处理器的4字节边界或64位处理器的8字节边界对齐的数据通常将被加载并存储在单个操作中.在较小边界上对齐的数据将需要多个操作来加载或存储.这比较慢. (4认同)

Ada*_*eld 32

如果可能的话,我通常会尽量避免使用#pragmas,因为它们非常依赖于编译器且不可移植.如果你想以便携方式使用它们,你必须使用#if/ #endifpair 包围每个pragma .GCC不鼓励使用pragma,实际上只支持其中一些与其他编译器的兼容性; GCC还有其他方法可以执行与其他编译器使用pragma相同的操作.

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

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

以下是你在GCC中做同样事情的方法:

struct PackedStructure __attribute__((__packed__))
{
  char a;
  int b;
  short c;
};
// sizeof(PackedStructure == 7)
Run Code Online (Sandbox Code Playgroud)

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

#define __attribute__(x)

而如果要移植MSVC代码,则必须用#if/ #endifpair 包围每个pragma .不漂亮.

  • 所以如果我想在MSVC上编译GCC代码并且需要打包结构我该怎么做呢? (3认同)
  • 对于gcc,它是`struct __attribute __((__ packed__))PackedStructure` (2认同)
  • 请注意,C99 和 C11 都包含 (C11) [§6.10.6 Pragma 指令](http://port70.net/~nsz/c/c11/n1570.html#6.10.6) 和 ¶1 _Any 这样的 pragma that is未被实现识别的将被忽略。_即使 C90 也这么说,尽管它在第 6.8.6 节中。(如果 GCC 在遇到它无法识别的编译指示时运行 `hack`,这使得 GCC 不合规,因为它曾经在很久以前曾经这样做过 - 参见 [`#pragma` 和 GCC](http ://toni.technetium.be/hacker/pragma.htm) 等) (2认同)

Sch*_*jer 15

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

另一种方法是使用包含防护装置(例如#ifndef MY_FILE #define MY_FILE ... #endif /* MY_FILE */)


小智 7

我觉得这#pragma是一个指令,如果你想让代码是特定于位置的.在某种情况下,你希望程序计数器从写入ISR的特定地址读取,那么你可以在那个位置指定ISR使用#pragma vector=ADC12_VECTOR和跟随中断rotines名称及其描述


Jus*_*ove 5

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

#pragma code BANK1
#pragma data BANK2

#pragma INT3 TimerHandler
Run Code Online (Sandbox Code Playgroud)

  • 所有pragma都是特定于实现的 - 除了#pragma STDC ... pragma,它们在所有平台上都是标准化的(除了C99之外). (3认同)

Bas*_*ANI 5

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

我只是想解释一个simple OpenMP example展示一些用途的#pragma来做它的工作

OpenMpbriefly是多平台共享内存并行编程的实现(那么我们可以说它是machine-specificoperating-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);
   }
}
Run Code Online (Sandbox Code Playgroud)

输出是

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.
Run Code Online (Sandbox Code Playgroud)

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

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

这只是many many applications你们中的一个可以用小#pragma

对外部样品感到抱歉 OpenMP