(操作方法)在特定的C ++年中获得有关过时/不推荐使用的功能/构造的编译器警告

时间:2019-07-08 13:10:52

标签: c++ c++17 compiler-warnings

我正在寻找一个编译器开关(或_SOME_MACRO),该开关将警告或禁止在“选定的” c ++年中不再建议(尽管仍然允许)的功能或构造。

例如当使用switch -std = c ++ 17编译g ++时,在使用已过时的取代“ typedef”构造时,我会发出警告。

也就是说,我想在c ++ 17的“正统c ++ 17”子集中进行编码;-)

typedef int Sequence; // I would like a warning here

编辑:更清楚地表达我的愿望:如果他们选择忽略任何向后兼容,那么我想使用作者将创建的理想的c ++ 17子集进行编程。我知道这不是严格的正式和真实的陈述,但我相信这足以说明我的观点。

2 个答案:

答案 0 :(得分:2)

好吧,有了gcc和一些宏滥用,您可以执行以下操作:

#define typedef _Pragma("GCC warning \"typedef is deprecated in my code base\"") typedef

typedef int Sequence; // I would like a warning here

将在gcc中生成:

<source>:3:13: warning: typedef is deprecated in my code base
    3 |     typedef int Sequence; // I would like a warning here
      |             ^~~~~~~~~~~~~~~~~~~~~~~

您可以将_Pragma("GCC warning \"string\"")更改为_Pragma("message \"string\")或实际上更改为_Pragma("GCC error \"string\"")以获得编译错误。您可以将其作为参数添加到编译行-D'typedef=_Pragma("GCC warning \"I consider typedef to be deprecated\"")'中。

C ++具有[[deprecated]],但它不赞成使用变量,而不赞成使用typedef,因此它没有适当的用途。它将在更多的编译器上工作,因此,如果您的团队/您同意一个约定,则可以使用它,以暗示您同意不在代码中使用typedef

#define typedef [[deprecated]] typedef

typedef int Sequence; // I would like a warning here

int main() { 
    Sequence a;
}

将在gcc 9.1中输出:

<source>: In function 'int main()':
<source>:6:14: warning: 'Sequence' is deprecated [-Wdeprecated-declarations]
    6 |     Sequence a;
      |              ^
<source>:3:13: note: declared here
    3 | typedef int Sequence; // I would like a warning here
      |             ^~~~~~~~

答案 1 :(得分:1)

您可能已经猜到,由于typedef是编译器指令,而不是函数或类,因此无法像使用#undef然后重新定义函数或宏的方式来重新定义它

#include <cstdio>
#undef printf

[[deprecated( “please don’t use printf!” )]]
int printf(const char *format, ...) {

您最好的选择是将clang-tidy之类的linter绑定到构建系统中以预处理语法。毕竟,您想给 programmer 而不是编译器一个警告指令。明智的做法是让编译器进行编译,而不给它其他工作。

此外,请记住typedef是完全有效的C ++,并且在类型别名之外具有实用性,与union的有效方式相同,并且即使std::variant可用,它也可以发挥作用。

编译器开发人员会在标准委员会完全淘汰某个构造时自行添加这些警告。 register是一个很好的例子。