Klang complains about undefined constexpr function in an invaluable context

Im using a simple SFINAE trick to check if a member function exists, for example:

#include <type_traits> template <typename C> struct has_size { template <typename T> static constexpr auto check(T*) -> decltype(std::declval<T const>().size(), std::true_type{}); template <typename> static constexpr auto check(...) -> std::false_type; static constexpr bool value = decltype(check<C>(nullptr))::value; }; // Usage: static_assert(has_size<std::vector<int>>::value, "std::vector<int> has size()"); 

(Im aware that theres a simpler method now, but didn't come back when I wrote this piece of code.)

This code works on GCC. However, Clang issues warning 1 (all versions prior to Apple LLVM 7.3, depending on whatโ€™s at the top):

 decltype.cpp:15:27: error: inline function 'has_size<std::__1::vector<int, std::__1::allocator<int> > >::check<std::__1::vector<int, std::__1::allocator<int> > >' is not defined [-Werror,-Wundefined-inline] static constexpr auto check(T*) -> ^ decltype.cpp:22:44: note: used here static constexpr bool value = decltype(check<C>(nullptr))::value; 

In other words, clang expects functions to be defined, not just declared, even if they are never called (only in an invaluable decltype context).

Is this a bug in clang? Or is it a right to complain? If so, is GCC correct when accepting this code?

Also, when writing this question, I realized that clang compilation errors can be avoided altogether by removing the constexpr qualifier before the member function template. What changes the presence of constexpr ?


1 What is the problem for compiling Im using -Werror . There are some warnings that are based on heuristics and therefore have unavoidable false positives, but this is not as far as I can see.

+6
source share
2 answers

If you are not going to name a function, there is no point denoting it constexpr .

constexpr function is not visible to the type system (well, except that pre-C ++ 14 had the side effect of creating a non-static const member function); rather, it promises that for at least one combination of arguments such as a template and function arguments (and the state of an object for a non-static member function), the body of the function can be evaluated as a constant expression (or an algorithm equivalent to a constant expression). Conversely, the lack of a constexpr function is an instruction for the compiler not to even try to evaluate the function body as a constant expression.

Clang is incorrect, but it is also not incorrect, because you specifically asked him to reject existing programs (using -Werror ). You should accept the warning as a strong hint that constexpr functions without a definition are a bad idea.

+2
source

Is this a bug in clang? Or is it a right to complain? If so, is GCC also correct in accepting this code?

Also, when writing this question, I realized that compiling clang errors can generally be avoided by removing the constexpr qualifier in front of the member function template. What will change the presence of constexpr here?

Compiler warnings are outside the scope of the C ++ standard. Warnings are issued for valid programs containing signs of human error. In your particular case, you selected a qualification with a constexpr function that you did not define. Programs that use this class will only be valid if you never call this function. If this is true, then constexpr not required. But what if you intended to call this function (although you forgot to provide an implementation for it), but due to some error (complex overload resolution or just a silly typo) another function was called?

Thus, Clang makes sense to issue a warning. However, it can be argued that this situation deserves a warning; I personally would not file an error against the GCC.

+2
source

All Articles