我遇到了一对不寻常的编译器警告,它们似乎相互矛盾。这是我写的代码:
#include <functional>
#include <iostream>
namespace {
std::function<void()> callback = [] {
void theRealCallback(); // Forward-declare theRealCallback
theRealCallback(); // Invoke theRealCallback
};
void theRealCallback() {
std::cout << "theRealCallback was called." << std::endl;
}
}
int main() {
callback();
}
换句话说,我在未命名的命名空间中定义了一个 lambda 函数,该函数前向声明了稍后在该未命名命名空间中定义的函数。
当我使用 g++ 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1) 编译此代码时,我收到以下两个警告:
CompilerWarningsNamespace.cpp:6:10: warning: ‘void {anonymous}::theRealCallback()’ used but never defined
void theRealCallback();
^~~~~~~~~~~~~~~
CompilerWarningsNamespace.cpp:10:8: warning: ‘void {anonymous}::theRealCallback()’ defined but not used [-Wunused-function]
void theRealCallback() {
^~~~~~~~~~~~~~~
这很奇怪,因为第一个警告说我正在使用一个没有定义它的函数,而第二个警告说我正在定义一个没有使用它的函数。
运行这个程序确实会产生输出
theRealCallback was called.
程序正常终止。
有趣的是,如果我不使用未命名的命名空间,而是为命名空间命名,这些警告就会消失,如下所示:
#include <functional>
#include <iostream>
namespace NamedNamespace {
std::function<void()> callback = [] {
void theRealCallback();
theRealCallback();
};
void theRealCallback() {
std::cout << "theRealCallback was called." << std::endl;
}
}
int main() {
NamedNamespace::callback();
}
代码的修改版本,与原始代码一样,打印出一条消息,指示theRealCallback
已调用。
有人可以解释为什么我会收到这些警告吗?我的猜测是,这与 lambda 函数中函数的前向声明有关,因为它被解释为出现在未命名命名空间中的后一个函数之外的东西,但如果是这种情况,我不确定我看到为什么这个链接最终以及为什么我收到这些警告。