5

使用的代码的可移植性如何#pragma optimize?大多数编译器是否支持它,对此的支持有多完整#pragma

4

5 回答 5

11

#pragma是编译器添加非认可和不可移植语言扩展的认可和可移植方式*

基本上,您永远无法确定,并且至少有一个主要的 C++ 编译器 (g++) 不支持此编译指示。


* :

来自 C++ 标准(N3242):

16.6 Pragma 指令[cpp.pragma]

形式的预处理指令

# pragma pp-tokens选择换行符

导致实现以实现定义的方式运行。该行为可能会导致翻译失败或导致翻译器或生成的程序以不合格的方式运行。任何未被实现识别的编译指示都会被忽略。

来自 C 标准(委员会草案 — 2011 年 4 月 12 日):

6.10.6 Pragma 指令

语义

形式的预处理指令

# pragma pp-tokens选择换行符

其中预处理标记STDC没有立即跟随pragma在指令中(在任何宏替换之前)174)导致实现以实现定义的方式运行。该行为可能会导致翻译失败或导致翻译器或生成的程序以不合格的方式运行。任何 pragma不被实现识别的内容都将被忽略。

这是一个例子:

int main () {
    #pragma omp parallel for
    for (int i=0; i<16; ++i) {}
}

C 和 C++ OpenMP API 的很大一部分是作为#pragmas 实现的。

于 2012-11-07T10:29:08.303 回答
6

依赖编译器标志通常不是一个好主意,因为每个编译器都有自己的行为。

不应使用此标志,因为它是您注入代码的编译级别规范。

通常和理论上,如果不使用此标志,编译器应忽略此标志。

于 2012-11-07T10:28:01.337 回答
3

关键字是可移植的#pragma,因为它应该始终编译,尽管在编译器上。但是,编译指示是特定于编译器的,因此在更改编译器时可能会抱怨一些警告。一些编译指示被广泛使用,例如来自 OpenMP 的编译指示。为了使代码尽可能地具有可移植性,您可以使用#ifdef/包围您的编译指示,#endif这取决于您使用的编译器。例如:

#ifdef __ICC
   #pragma optimize
#endif

编译器通常定义一些宏,例如__ICC使代码知道正在使用哪个编译器。

于 2012-11-07T10:43:51.183 回答
1

#pragma不便携,句号。有一个版本的 gcc 曾经在遇到它时开始游戏

我们在工作中使用的编译器中,有两个肯定不支持#pragma optimise,其他的我也无法回答。

即使他们这样做了,由于用于优化的命令行开关不同,编译指示的选项也可能不同。

于 2012-11-07T10:31:12.587 回答
1

的任何使用#pragma都是特定于编译器的。

例如: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.")

关于您关于 的具体问题, gccmicrosoft#pragma optimize都支持,但这并不意味着将来会支持。

于 2012-11-07T10:32:35.180 回答