该标准允许#pragma做什么?

cel*_*chk 5 c++ language-lawyer

在C++(和C)中,我们有一个#pragma基本上具有实现定义效果的指令.但是,该指令可能有什么限制吗?(请注意,我在询问标准允许的内容,而不是真正的编译器实际执行的内容.)

我肯定#pragma可以这样做:

  • 允许选择几个编译选项中的一个,这些选项都会产生有效的C++ - 例如,选择几个可用的ABI之一,或切换某些实现定义的选项.

我猜是允许的,但不确定:

  • 允许编译器接受其他非法代码而不发出诊断(例如,编译器可能决定支持新的内置类型long long long,但使用该代码的任何代码都必须发出诊断;然后可以使用例如#pragma long long long.

  • 允许编译器拒绝其他合法代码,例如可能存在#pragma strict导致编译器将某些库函数和/或被认为不安全的语言结构的使用标记为错误的错误.

我实际上怀疑是允许的,但我也不确定:

  • 允许编译器将合法代码的语义更改为不同的语句(例如,假设编译器供应商认为for条件是后置条件(如do... while)是一个好主意,并定义#pragma for postcondion为相应地切换其含义for.

我怀疑后者的原因是允许编译器忽略它无法识别的任何编译指示,因此编译指示语义的改变会导致同一程序在不同的编译器上具有不同的语义.

但是,标准实际允许什么?是否有允许的内容,但上面列表中没有涵盖哪些内容?

fil*_*mor 5

标准非常明确:

[cpp.pragma]表单的预处理指令

#pragma pp-tokensopt new-line
Run Code Online (Sandbox Code Playgroud)

导致实现以实现定义的方式运行.该行为可能导致转换失败或导致转换程序或生成的程序以不符合的方式运行.将忽略实现无法识别的任何编译指示.

因此编译器可以在看到它时做任何想做的事情#pragma.