关于未使用变量的奇怪编译器警告,这是编译器错误吗?

Posted

技术标签:

【中文标题】关于未使用变量的奇怪编译器警告,这是编译器错误吗?【英文标题】:Weird compiler warning about unused variable, is this a compiler bug? 【发布时间】:2019-04-21 19:08:55 【问题描述】:

我的问题是关于以下代码:

#include <type_traits>
#include <utility>

template <int First, int Last, typename Functor>
constexpr void static_for(Functor&& f)

    if constexpr (First < Last)
    
        f(std::integral_constant<int, First>);
        static_for<First + 1, Last, Functor>(std::forward<Functor>(f));
    


int main() 
    static_for<1, 3>([](int /*i*/)

    );
    return 0;

它使用 MSVC(Visual Studio 2017 15.9.11,v141 工具集,/std:c++17)产生以下编译器警告:

警告 C4100:'f':未引用的形式参数

它可以在 Godbolt 上重现:https://godbolt.org/z/6gLDzu

这是编译器错误吗?我打算向 Microsoft 报告它,但后来想征求社区的意见,也许我遗漏了什么? 代码确实有效,并且仿函数被调用了正确的次数,因此编译器不会错误地编译代码并错误地优化 f

【问题讨论】:

更像是一个 QoI 问题,with workarounds。 在 First >= Last 的情况下,if constexpr 导致整个函数体消失,f 未被使用。 @RaymondChen:但是在编译这段代码 sn-p 期间不会发生这种情况,编译器在发出警告之前不应该看到吗?在我看来,警告好像是基于一些启发式而不是实际的 AST 生成的,我觉得这很奇怪。 当然会发生。 First + 1 不会无限期地继续下去。 This post 有一个高效的基本 static_for 来自我。 【参考方案1】:

static_for() 的最后一次迭代中,First + 1 等于 Last。 这会导致函数体消失,f 未被使用。

【讨论】:

以上是关于关于未使用变量的奇怪编译器警告,这是编译器错误吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何抑制有关 C++ 中未使用变量的警告?

VS2012的错误警告问题

gcc编译选项-Wall(编译警告:未使用变量变量未初始化类型转换等)

编译器处理警告错误 #pragma GCC diagnostic ignored "-Wunused"

GCC 常用编译选项

编译器未捕获未初始化的成员。它是一个错误吗?