使用#pragma optimize
的代码的可移植性如何?大多数编译器是否支持它以及对此#pragma
的支持有多完整?
答案 0 :(得分:11)
#pragma
是认可且可移植的方式,供编译器添加非认可和非可移植的语言扩展 * 。
基本上,你永远不会确定,并且至少有一个主要的C ++编译器(g ++)不支持这个pragma。
* :
来自C ++标准(N3242):
16.6 Pragma指令 [cpp.pragma]
表单
的预处理指令
# pragma
pp-tokens opt new-line使实现以实现定义的方式运行。该行为可能导致转换失败或导致转换程序或生成的程序以不符合的方式运行。将忽略实现无法识别的任何编译指示。
根据C标准(委员会草案 - 2011年4月12日):
6.10.6 Pragma指令
语义
表单
的预处理指令
# pragma
pp-tokens opt new-line预处理令牌
。忽略了实现无法识别的STDC
不会立即跟随pragma
指令(在任何宏替换之前) 174)导致实现在行为中 实现定义的方式。该行为可能导致转换失败或导致 翻译或由此产生的程序以不符合的方式行事。任何这样的pragma
。
这是一个例子:
int main () {
#pragma omp parallel for
for (int i=0; i<16; ++i) {}
}
C和C ++ OpenMP API的很大一部分实现为#pragma
s。
答案 1 :(得分:6)
依靠编译器标志通常不是一个好主意,因为每个编译器都有自己的行为。
不应使用此标志,因为它是您注入代码的编译级别规范。
通常情况下,理论上如果不使用,编译器应忽略此标志。
答案 2 :(得分:3)
#pragma
关键字是可移植的,因为它应该始终在编译器上编译。但是,pragma是特定于编译器的,因此在更改编译器时可能会抱怨一些警告。一些pragma被广泛使用,例如OpenMP中的这些。为了使代码尽可能便于使用,您可以使用依赖于您正在使用的编译器的#ifdef
/ #endif
来包围您的编译指示。例如:
#ifdef __ICC
#pragma optimize
#endif
编译器通常定义一些宏,例如__ICC
,使代码知道正在使用哪个编译器。
答案 3 :(得分:1)
#pragma
不可移植,完全停止。有一个版本的gcc,只要碰到那个游戏就会用来开始游戏
我们在工作中使用的编译器中,有两个肯定不支持#pragma optimise
,我无法回答其他编译器。
即使他们这样做了,因为用于优化的命令行开关是不同的,pragma的选项可能会有所不同。
答案 4 :(得分:1)
#pragma
的任何使用都是特定于编译器的。
For example: GNU,英特尔和IBM:
#warning "Do not use ABC, which is deprecated. Use XYZ instead."
微软:
#pragma message("Do not use ABC, which is deprecated. Use XYZ instead.")