125

C中有什么用处#pragma,有例子吗?

4

10 回答 10

74

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

有关详细信息,请参阅msdn

于 2008-10-24T08:03:12.230 回答
58

#pragma用于在 C 中做一些特定于实现的事情,即在当前上下文中务实而不是意识形态上的教条。

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

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

于 2008-10-24T08:00:34.247 回答
38

I would generally try to avoid the use of #pragmas if possible, since they're extremely compiler-dependent and non-portable. If you want to use them in a portable fashion, you'll have to surround every pragma with a #if/#endif pair. GCC discourages the use of pragmas, and really only supports some of them for compatibility with other compilers; GCC has other ways of doing the same things that other compilers use pragmas for.

For example, here's how you'd ensure that a structure is packed tightly (i.e. no padding between members) in MSVC:

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

Here's how you'd do the same thing in GCC:

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

The GCC code is more portable, because if you want to compile that with a non-GCC compiler, all you have to do is

#define __attribute__(x)

Whereas if you want to port the MSVC code, you have to surround each pragma with a #if/#endif pair. Not pretty.

于 2008-10-25T04:57:37.927 回答
17

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

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

于 2008-10-24T07:58:38.387 回答
7

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

于 2012-11-30T05:56:13.420 回答
6

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

#pragma code BANK1
#pragma data BANK2

#pragma INT3 TimerHandler
于 2008-10-25T04:47:56.323 回答
5

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

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

OpenMpbriefly是一种多平台共享内存并行编程的实现(那么我们可以说它是machine-specificor 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

于 2016-05-02T14:45:48.990 回答
3

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

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

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

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

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

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

于 2014-06-05T09:27:30.313 回答
3

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

#pragma startup func1
#pragma exit func2

在这里,先func1运行后运行。mainfunc2

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

void __attribute__((constructor)) func1();
void __attribute__((destructor)) func2();
于 2016-02-03T20:53:45.747 回答
2

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

  • #pragma可用于忽略编译器警告。例如,要让 GCC 对隐式函数声明闭嘴,你可以这样写:

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

    较旧的版本可移植libportable地执行此操作。

  • #pragma once,当写在头文件的顶部时,将导致该头文件被包含一次。libportable 检查编译指示一旦支持。

于 2017-03-08T17:01:43.030 回答