43

实现弃用警告的一种方法是在调用弃用函数时生成警告,除非您从弃用的上下文中调用。这样,遗留代码可以调用遗留代码,而不会产生仅相当于噪音的警告。

这是一个合理的思路,它反映在我在 OS X 上的 GCC 4.2 (1) 和 Clang 4.0 (2) 以及 Ubuntu 上的 Clang 3.0 (3) 中看到的实现。

  • (1):i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1(基于 Apple Inc. build 5658)(LLVM build 2336.11.00)
  • (2):Apple clang 4.0 版本(tags/Apple/clang-421.0.57)(基于LLVM 3.1svn)
  • (3):Ubuntu clang 3.0-6ubuntu3 版本(tags/RELEASE_30/final)(基于LLVM 3.0)

但是,当我在 Ubuntu 上使用 GCC 4.6 (4) 进行编译时,我会收到所有已弃用函数调用的弃用警告,与上下文无关。这是功能的回归吗?是否有我可以用来获得其他行为的编译器选项?

  • (4): g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3

示例程序:

int __attribute__((deprecated)) a() {
    return 10;
}

int __attribute__((deprecated)) b() {
    return a() * 2; //< I want to get rid of warnings from this line
}

int main() {
    return b(); //< I expect a warning on this line only
}

GCC 4.2 的输出(是的,我确实收到了两次相同的警告。不过,我不在乎):

main.cpp: In function ‘int main()’:
main.cpp:10: warning: ‘b’ is deprecated (declared at main.cpp:5)
main.cpp:10: warning: ‘b’ is deprecated (declared at main.cpp:5)

GCC 4.6 的输出:

main.cpp: In function 'int b()':
main.cpp:6:9: warning: 'int a()' is deprecated (declared at main.cpp:1) [-Wdeprecated-declarations]
main.cpp:6:11: warning: 'int a()' is deprecated (declared at main.cpp:1) [-Wdeprecated-declarations]
main.cpp: In function 'int main()':
main.cpp:10:9: warning: 'int b()' is deprecated (declared at main.cpp:5) [-Wdeprecated-declarations]
main.cpp:10:11: warning: 'int b()' is deprecated (declared at main.cpp:5) [-Wdeprecated-declarations]

如何说服 GCC 4.6 它应该给我与 GCC 4.2 相同的输出?

4

4 回答 4

53

-Wno-deprecated将删除所有已弃用的警告

于 2012-11-19T18:14:05.937 回答
53

gcc 4.6 添加了有助于解决此问题的诊断编译指示:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
int __attribute__((deprecated)) b() {
   return a() * 2; //< I want to get rid of warnings from this line
}
#pragma GCC diagnostic pop

注意:这只适用于 gcc 4.6 及更高版本。pushandpop是 4.6 扩展。在 gcc 4.5 中,#pragma GCC diagnostic pushandpop将被忽略(带有警告)。不会被忽略的是#pragma GCC diagnostic ignored "-Wdeprecated-declarations"-- 但现在这一直有效,直到文件结束。

于 2012-11-19T18:33:10.237 回答
19

您在 GCC 4.2 中看到的行为是由 Apple 特定的 GCC 补丁引起的。FSF GCC 4.2.4 警告使用a. Apple GCC 具有 FSF GCC 所没有的特定位是:

--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -902,6 +902,9 @@ warn_deprecated_use (tree node)
   if (node == 0 || !warn_deprecated_decl)
     return;

+  if (current_function_decl && TREE_DEPRECATED (current_function_decl))
+    return;
+
   if (DECL_P (node))
     {
       expanded_location xloc = expand_location (DECL_SOURCE_LOCATION (node));

(在 GPLv2 或更高版本下可用)

您可能希望将此补丁修改为更高版本的 GCC(可能不需要更改,可能需要进行重大更改),并使用此补丁从源代码构建 GCC。或者您可以在 FSF GCC bugzilla 上将此报告为功能请求。

于 2012-11-19T20:04:24.887 回答
1

我遇到同样的问题。提出的解决方案如下

typedef OLD_A_NOT_TO_BE_USED a __attribute__((deprecated));

int OLD_A_NOT_TO_BE_USED () {
    return 10;
}

int __attribute__((deprecated)) b() {
    return OLD_A_NOT_TO_BE_USED () * 2; //< I want to get rid of warnings from this line
}

int main() {
    return b(); //< I expect a warning on this line only
}

所以我只是将我的类重命名为 OLD_A_NOT_TO_BE_USED 类。我只在 return b(); 时收到警告。如果有人使用 a 他们仍然会收到弃用的警告。

于 2015-01-27T20:09:56.543 回答