Вопрос

In clang I get this warning

warning: inline function 'detail::selector<2, int>::select' is not defined [-Wundefined-inline]
    static constexpr auto select(T const&) -> std::integral_constant<int, Which>;
                          ^

note: used here
static_assert( decltype(Selector::select(int()))::value == 2, "");
                                  ^

in the code below.

Is NOT defining the function here harmful? (I strongly believe, it doesn't matter here and in my application, since it's used in unevaluated context, in std::enable_if).

Now, I'm wondering when the compiler thinks it should issue a warning.

#include <type_traits>

namespace detail {

    template <int Which, typename...> struct selector;

    template <int Which>
    struct selector<Which> {
        static constexpr void select();  // never select
    };

    template <int Which, typename T, typename... Ts>
    struct selector<Which, T, Ts...> : selector<Which+1, Ts...>
    {
        using selector<Which+1, Ts...>::select;
        static constexpr auto select(T const&) -> std::integral_constant<int, Which>;
    };
}

int main(int argc, const char * argv[])
{
    using Selector = detail::selector<0, char, short, int>;
    static_assert( decltype(Selector::select(int()))::value == 2, "");    
    return 0;
}

Edit:

Notes:

  • gcc-4.8.1 on ideone.com does not issue a warning.

  • The simplest way to get rid of the warning is providing an implementation, e.g.:

    static constexpr auto select(T const&) 
    -> std::integral_constant<int, Which> 
    { return {}; }
    

    (thanks @Yakk)


Solution:

As explained in the answer provided by @Filip Roséen the constexpr specifier will implicitly declare that function inline, which requires a definition WHEN it is evaluated. The function is not used in my code, though - but nonetheless clang will issue that warning (indicating a minor issue in the compiler). clang will not issue this warning anymore, when the constexpr specifier is omitted. The constexpr specifier seems to be inappropriate anyway, (thanks @Yakk).

Это было полезно?

Решение

Note; as stated the diagnostic issued by clang is a mere warning and not an error, which means that it's just there to attract our attention to a segment which might be misused if not handled correctly.


What might potentially go wrong?

Entities marked as constexpr are implicitly inline (which is also true for functions defined directly within a class), as stated in [dcl.fct.spec]p3.

Functions having the inline specifier, implicitly or not, must follow the rules applied to such. The warning issued by clang is there to warn developers of writing code that violates the following (among others):

[dcl.fct.spec]

4) An inline function shall be defined in every translation unit in which it is odr-used and shall have exactly the same definition in every case (3.2).

[basic.def.odr]

2) An expression is potentially evaluated unless it is an unevaluated operand (Clause 5) ...

3) A variable x whose name appears as a potentially-evaluated expression ex is odr-used ...

4) ... An inline function shall be defined in every translation unit in which it is odr-used and shall have exactly the same definition in every case (3.2).


Is clang correct to issue -Wundefined-inline in our context?

Technically... No, the warning is of no value since our usage of select doesn't violate the one definition rule in an unevaluated context.

You could supress the warning by passing -Wno-undefined-inline when invoking clang, and if this bothers you greatly please file a bug report.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top