Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does SFINAE not give the correct result for incrementing bool?

I wrote an is_incrementable trait like this:

#include <type_traits>

template <typename T, typename = void>
struct is_incrementable : std::false_type {};

template <typename T>
struct is_incrementable<T, std::void_t<decltype(++std::declval<T&>())>>
    : std::true_type {};

template <typename T>
constexpr bool is_incrementable_v = is_incrementable<T>::value;

When I apply it to bool with -std=c++17 on clang, it returns true:

// This compiles
static_assert(is_incrementable_v<bool>, "");

But incrementing bool is not allowed under c++17. Indeed, if I try to do it, I get an error:

bool b = false;
++b;

results in:

error: ISO C++17 does not allow incrementing expression of type bool [-Wincrement-bool]

Why does SFINAE report that bool is incrementable, when the compiler clearly doesn't allow it?

Compiler explorer: https://godbolt.org/g/DDFYBf

like image 423
Alastair Harrison Avatar asked Jun 24 '18 16:06

Alastair Harrison


1 Answers

It looks like Clang erroneously permits the incrementation of bool values in not-evaluated contexts.

We can simplify your example using C++20 concepts:

template<class T>
concept is_incrementable = requires(T t) {
    { ++t };
};

int main() {
    static_assert( is_incrementable<int> );
    static_assert( !is_incrementable<bool> ); // Clang error here
}

This program is accepted in GCC and MSVC, but Clang shows the same wrong behaviour here, demo: https://gcc.godbolt.org/z/YEnKfG8T5

I think it is Clang bug, so submitted a bug report: https://bugs.llvm.org/show_bug.cgi?id=52280

like image 74
Fedor Avatar answered Oct 14 '22 22:10

Fedor