【问题标题】:C++ Clang emit warning about unused template variableC++ Clang 发出有关未使用的模板变量的警告
【发布时间】:2021-04-07 13:06:46
【问题描述】:

C++ Clang 发出关于未使用模板变量的警告

考虑一个未使用的模板变量定义,比如这个:

template <typename T, typename = void>
struct is_complete : std::false_type {};
template <typename T>
struct is_complete<T, std::void_t<decltype(sizeof(T))>>
    : std::true_type {};
template <typename T>
constexpr static inline auto is_complete_v = is_complete<T>::value;

在这里,Clang 发出关于未使用的 is_complete_v 变量的警告,这对我来说似乎是错误的。
如果未使用,为什么要实例化这样的变量符号?也许我错过了一点。

warning: unused variable 'is_complete_v' [-Wunused-const-variable]
    static inline constexpr auto is_complete_v = is_complete_v<T>::value;
           

情况是,GCC 等其他编译器不会发出任何警告。
哪个 IMOO 有意义,因为该符号未解析。

我可以修复我正在使用的所有代码库:

template <typename T>
#if __clang__
[[maybe_unused]]
#endif
constexpr static inline auto is_complete_v = is_complete<T>::value;

或者通过禁用-Wunused-const-variable

但我想知道:

  • 有没有更简洁的方法来实现这一点?
  • 这是正常行为吗?

【问题讨论】:

  • 你能评论一下为什么is_complete_vstatic吗? Clang 可能会抱怨,因为它认识到该符号的任何实例都不可能在当前翻译单元之外使用,即使没有实例。
  • @Brian 感谢您指出这一点!这绝对是 C++ 标准迁移脚本的剩余部分,此后没有触发任何错误。事实上,-Wall 在使用 Clang 时被禁用(并且 Clang-CL /W4 没有触发它)。
  • 变量确实没有使用
  • @BЈовић 我不同意。对我来说,这个模板变量符号没有实例化,因此从符号生成的角度来看根本不存在。因此,它不应生成警告。相反,如果您告诉我 is_complete_v&lt;int&gt; 未使用,我会同意,因为这是一个定义明确的符号。
  • @Guss remove static 并且警告将消失。它没有很好的定义

标签: c++ c++17 clang++


【解决方案1】:

Clang“未使用”类诊断的启发式方法似乎根本不检查每个实例化,而是检查未实例化的模板本身。

我自己也遇到过类似的问题,特别是在依赖模板函数中的构造函数来产生副作用时(对于 RAII 等)。当 Clang 需要知道传递的模板参数以确定使用的构造函数时,它天真地将构造函数视为纯构造函数并将构造的变量标记为未使用(Wunused-variable),但如果无需实例化模板就可以确定构造函数,那么它不会将变量标记为未使用,因为它可以确定构造函数会产生可观察到的副作用。

在您的情况下,由于您的模板很可能无论如何都在头文件中,因此是否标记为static 没有区别。使用type traits 库“可能的实现”作为指导,避免将这些模板值标记为static 以避免诊断。

【讨论】:

  • 关于内部 Clang 行为的很好的解释,谢谢。我接受了这个答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-19
  • 2011-12-09
  • 2010-09-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多