为啥 C++ 已弃用的警告会打印两次?
Posted
技术标签:
【中文标题】为啥 C++ 已弃用的警告会打印两次?【英文标题】:Why do C++ deprecated warnings print twice?为什么 C++ 已弃用的警告会打印两次? 【发布时间】:2019-04-21 15:12:23 【问题描述】:如果我有
namespace foo
inline int bar()
return 1119;
__attribute__((deprecated)) inline int bar()
return 138;
在header.h
和
#include "header.h"
#include <iostream>
int main()
int x = bar();
int y = foo::bar();
std::cout << x << std::endl;
std::cout << y << std::endl;
在source.cpp
,然后
g++ source.cpp -o deprecated-test
结果
source.cpp: In function ‘int main()’:
source.cpp:5:17: warning: ‘int bar()’ is deprecated [-Wdeprecated-declarations]
int x = bar();
^
In file included from source.cpp:1:
header.h:7:40: note: declared here
__attribute__((deprecated)) int bar()
^~~
source.cpp:5:17: warning: ‘int bar()’ is deprecated [-Wdeprecated-declarations]
int x = bar();
^
In file included from source.cpp:1:
header.h:7:40: note: declared here
__attribute__((deprecated)) int bar()
(在带有 g++ 8.2.0 的 Ubuntu 18.10 上)。
为什么不推荐使用的警告会打印两次?
排除一些无用的建议:
[[deprecated]]
:
我知道在 C++14 上你可以使用 [[deprecated]]
属性,但我需要使用 C++11。
声明与定义:The docs 似乎暗示它应该与函数声明而不是定义一起使用,但是
-
我需要在头文件中定义函数
inline
,而不是在头文件中声明并在源文件中定义;和
尝试这种方法并没有阻止警告打印两次。
【问题讨论】:
可能是一个错误。 Clang 不会打印两个警告。[[deprecated]]
产生相同的结果(gcc 中的两个警告,clang 中的一个)。
@tkausl 谢谢,很高兴知道!看到 clang 不会两次打印警告,我可能还需要尝试其他 g++
版本,看看它是否是最近引入和/或最近修复的错误
gcc 版本高达 5.5 甚至打印 三个 警告...有趣。 godbolt.org/z/383Hl0
@tkausl 哇...另外,感谢您将我指向 godbolt.org 资源。我以前见过它,但忘记了它,没想到去那里尝试其他编译器
@tkausl 看起来只有 gcc 5.x 打印 3 个警告。 gcc 7.x 打印一个警告,所有其他(我检查过的)打印两个警告。获取已弃用函数的地址会在 gcc 5.x 中打印两个警告,对所有其他版本打印一个警告。
【参考方案1】:
根据 GCC 8.2.0 的文档:
不推荐使用的属性会导致警告如果该函数在任何地方使用 在源文件中。这在识别预期功能时很有用 将在程序的未来版本中删除。该警告还包括 弃用函数的声明位置,使用户能够轻松地 查找有关为什么不推荐使用该功能或它们是什么的更多信息 应该这样做。请注意,警告仅针对用途...
应该只有一个警告而不是两个。所以这是 GCC 中的一个错误。
Type 属性(而不是 Function 属性)有一个相关的 bug,标题为:C/C++ __attribute__((deprecated))
does not appear to wrap declarations as implied from the doc.
已确认为错误。
【讨论】:
这肯定是 GCC 中的一个错误,而不是您(以及从 cmets 到帖子的其他人)提到的我的代码的问题。您提到的相关错误很有趣,因为它们不会从一种用法中获得多个警告,而是对 not 使用的声明发出警告。看来我需要提交单独的错误报告。谢谢!以上是关于为啥 C++ 已弃用的警告会打印两次?的主要内容,如果未能解决你的问题,请参考以下文章
Apple 警告 ITMS-90809:收到已弃用的 API 使用情况
ConnectivityManager.TYPE_WIFI 在代码中显示已弃用。我在 M 以上版本中使用了网络功能,想要删除已弃用的警告