关于使用[[noreturn]]之外的属性的建议



在关于使用供应商特定属性的讨论中,我问自己另一个问题,"我们应该告诉人们使用标准中未列出的属性的规则是什么">

定义的两个属性是[[ noreturn ]][[ carries_dependencies ]]。该标准保留了编译器对未知属性的反应方式,因此,根据该标准,编译器可能会以错误消息停止。这不是例如GCC所做的,它会发出警告并继续。这可能是最常见的编译器所期望的行为。出于这个原因,我想在标准中读一个"应该",但我们没有

N2553提出了柔性属性。它列出了GCC使用的其他属性(unusedweak(和MSVC(dllimport(。对于广泛支持的并行化框架OpenMP,提出了作用域属性,如omp::for(clause, clause)omp::parallel(clause,clause)。因此,我们很可能会在一些供应商特定的属性支持语法后很快使用这些属性。

因此,当我们现在"走出去",告诉人们C++11时,关于使用属性的建议应该是什么

  • 仅使用noreturncarries_dependencies
  • 使用编译器的旧语法,例如__attribute__((noreturn)),并在移植代码时定义宏(当前情况(
  • 自由使用你喜欢的编译器支持的那些属性,因为你知道这些代码可能无法移植到另一个符合标准的编译器,因为如果标准允许编译器因错误而停止,你必须考虑这种情况会发生。这听起来有点像提倡编写不可移植的代码
  • 或者,我想,最常用的编译器应该警告未知属性,这样您就可以使用特定于供应商的属性,记住在极少数情况下您可能会遇到问题

请注意最后两个项目符号中的细微差异。虽然两者都说"使用您需要的属性",但第3项的信息是"不关心其他编译器",而第4项则隐式地将标准文本"实现定义的行为"改写为"编译器应该发出诊断消息"。

对于即将推出的最佳实践有什么建议

最佳实践是使用宏,这是唯一一种在实践中可以合理移植的实践,更不用说标准中的模糊性了。我们还需要很多年才能忘记不支持属性的编译器。

编译器的数量和这些编译器定义的自定义__keywords__的数量将一直在增加,语言定义一种控制损坏的方法是有意义的。它不需要彻底改变人们编写不可移植代码的方式,也不需要使不可移植的代码具有可移植性(尽管标准属性可以做到这一点(。当他们想要扩展语法时,只需为添加咖啡因的编译器后端工程师提供一个沙盒就可以了。

然而,有点令人担忧的是,除了当前标准的属性令牌之外,没有为实现或语言保留任何属性令牌。因此,当他们决定对它们进行更多的标准化时,就会遇到麻烦。

最新更新