C中#pragma
的一些用途是什么?
答案 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
此处func1
在main
之前运行,func2
之后运行。
注意:此代码仅适用于Turbo-C编译器。要在GCC中实现此功能,您可以像这样声明func1
和func2
:
void __attribute__((constructor)) func1();
void __attribute__((destructor)) func2();
答案 8 :(得分:3)
上面的所有答案都为#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
答案 9 :(得分:2)
总结一下,#pragma
告诉编译器要做的事情。以下是我使用它的几种方法:
#pragma
可用于忽略编译器警告。例如,要使GCC关闭隐式函数声明,可以编写:
#pragma GCC diagnostic ignored "-Wimplicit-function-declaration"
较早版本的libportable
执行此操作portably。
#pragma once
,当写在头文件的顶部时,将导致所述头文件被包含一次。 libportable
checks支持pragma。