在C中使用#pragma

时间:2008-10-24 07:56:02

标签: c pragma

C中#pragma的一些用途是什么?

10 个答案:

答案 0 :(得分:58)

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

有关详细信息,请参阅msdn

答案 1 :(得分:49)

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

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

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

答案 2 :(得分:31)

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

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

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

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

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

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

#define __attribute__(x)

如果您想要移植MSVC代码,则必须使用#if / #endif对包围每个编译指示。不漂亮。

答案 3 :(得分:14)

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

另一种方法是使用包含警戒(例如#ifndef MY_FILE #define MY_FILE ... #endif /* MY_FILE */

答案 4 :(得分:7)

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

答案 5 :(得分:5)

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

#pragma code BANK1
#pragma data BANK2

#pragma INT3 TimerHandler

答案 6 :(得分:3)

这是一个预处理程序指令,可用于打开或关闭某些功能。

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

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

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

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

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

答案 7 :(得分:3)

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

#pragma startup func1
#pragma exit func2

此处func1main之前运行,func2之后运行。

注意:此代码仅适用于Turbo-C编译器。要在GCC中实现此功能,您可以像这样声明func1func2

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

答案 8 :(得分:3)

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

我只是想解释simple OpenMP example演示#pragma用于工作的一些用途

  

OpenMp briefly是多平台共享内存的实现   并行编程   (然后我们可以说它是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);
   }
}

输出

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

答案 9 :(得分:2)

总结一下,#pragma告诉编译器要做的事情。以下是我使用它的几种方法:

  • #pragma可用于忽略编译器警告。例如,要使GCC关闭隐式函数声明,可以编写:

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

    较早版本的libportable执行此操作portably

  • #pragma once,当写在头文件的顶部时,将导致所述头文件被包含一次。 libportable checks支持pragma。