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

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

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

但我想知道:

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

最佳答案

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

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

就您而言,由于您的模板很可能位于头文件中,因此无论是否标记为 static 都没有区别。使用type traits库“可能的实现”作为指导,并避免将这些模板值标记为静态以避免诊断。

关于C++ Clang 发出有关未使用模板变量的警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66986718/

相关文章:

c++ - 在 constexpr 函数中使用 MSVC 的 __popcnt

c++ - 未定义的行为或误报

c++ - VS 代码 C++ : inaccurate system includePath errors (wchar. h,boost/lambda/lambda.hpp)

c++ - 是否可以在 C++17 的 GCC 中使用显式寄存器变量?

xcode - 使用clang++ 4.2时,“选择的构造函数在复制初始化错误中是显式的”

c++ - 如何将行进方 block 用于多个轮廓?

c++ - 通过两个不同的可执行文件进行 IPC?

C++继承和类内继承变量

c++ - Lock/CriticalSection 与 c++ 中的 volatile 的可见性

c++ - 现代 C++ 实现具有可变数量的 int 参数的函数的最佳方法