C++ Clang emit warning about unused template variable

Viewed 341

C++ Clang emit warning about unused template variable

Considering an unused template variable definition, such as this one :

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;

Here, Clang emit a warning about unused is_complete_v variable, which seems wrong to me.
Why would such variable symbol be instanciated at all, if unused ? Perhaps I'm missing a point.

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

The case is, other compiliers like GCC does not emit any warning.
Which IMOO makes sens, as the symbol is not resolved.

I could fix up all the codebases I'm working with using either :

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

Or by disabling -Wunused-const-variable,

But I wonder if :

  • Is there a cleaner way to achieve this ?
  • Is this a normal behavior ?
1 Answers

The heuristics for the Clang "unused" class of diagnostics don't appear to inspect each instantiation at all, but rather the uninstantiated template itself.

I've experienced similar issues myself, specifically when relying on constructors within template functions to produce side effects (for RAII, etc.). When Clang needs to know the template parameter passed in order to determine the constructor that was used, it naively treats the constructor as pure and marks the constructed variable unused (Wunused-variable), but if the constructor can be determined without instantiating the template, then it will not mark the variable unused because it can determine that the constructor produces an observable side-effect.

In your case, since it's likely that your template is in a header file anyway, it makes no difference whether it's marked static or not. Use the type traits library "possible implementations" as a guide and avoid marking these template values as static in order to avoid the diagnostic.

Related