在C中使用#pragma
C语言中#pragma
一些用法,用什么例子?
#pragma
是针对机器特定的或操作系统特定的编译器指令,即它告诉编译器执行某些操作,设置某个选项,采取某些操作,覆盖某些默认值等,这些操作可能适用于所有机器和操作系统。
有关更多信息,请参阅msdn 。
#pragma
被用来在C语言中做一些特定于实现的事情,也就是说,对于当前的情况而言是务实的,而不是意识形态上的教条式的。
我经常使用的是#pragma pack(1)
,我试图从embedded式解决scheme的内存空间中挤出更多的内存空间,而数组结构本来是以8字节alignment的。
可惜我们还没有#dogma
。 这应该很有趣 ;)
我一般会尽量避免使用#pragmas,因为它们是非常依赖于编译器的,而且是不可移植的。 如果您想以便携的方式使用它们,则必须用#if /#endif对来包围每个附注。 GCC不鼓励使用编译指示,实际上只支持其中的一些与其他编译器兼容; 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对包围每个附注。 不漂亮。
将#pragma once
放在头文件的顶部将确保只包含一次。 请注意, #pragma once
不是标准的C99,但被大多数现代编译器所支持。
另一种方法是使用包含警卫(例如#ifndef MY_FILE #define MYFILE ... #endif
)
我的感受是#pragma
是一个指令,如果你希望代码是位置特定的,那么你希望程序计数器从写入ISR的特定地址读取的情况下,你可以使用#pragma vector=ADC12_VECTOR
, #pragma vector=ADC12_VECTOR
中断旋转名称及其描述
我最好的build议是看你的编译器的文档,因为根据定义,编译指示是特定于实现的。 例如,在embedded式项目中,我使用它们来定位不同部分的代码和数据,或者声明中断处理程序。 即:
#pragma code BANK1 #pragma data BANK2 #pragma INT3 TimerHandler
这是一个预处理器指令,可用于打开或closures某些function。
它有两种types: #pragma startup
, #pragma exit
和#pragma warn
。
#pragma startup
允许我们指定程序启动时调用的函数。
#pragma exit
允许我们指定程序退出时调用的函数。
#pragma warn
告诉计算机禁止任何警告。
许多其他的#pragma
风格可以用来控制编译器。
综上所述, #pragma
告诉编译器做些什么。 以下是我使用它的几种方法:
-
#pragma
可以用来忽略编译器警告。 例如,为了让GCCclosures隐式函数声明,可以这样写:#pragma GCC diagnostic ignored "-Wimplicit-function-declaration"
旧版本的
libportable
这样做是可移植的 。 -
#pragma once
写在头文件的顶部,会导致头文件被包含一次。libportable
检查编译指示一旦支持。
上面的所有答案都为#pragma
很好的解释,但是我想添加一个小例子
我只是想解释一个simple OpenMP example
,它演示了#pragma
一些用法来完成它的工作
OpenMp是一个多平台共享内存并行编程的实现(然后我们可以说它是
machine-specific
或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 startup
是一个指令,用于在main函数之前调用一个函数,并在main函数之后调用另一个函数,例如
#pragma startup func1 #pragma exit func2
这里, func1
在main
和func2
之后运行。
注意:此代码仅适用于Turbo-C编译器。 为了在GCC中实现这个function,你可以像这样声明func1
和func2
:
void __attribute__((constructor)) func1(); void __attribute__((destructor)) func2();