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

1

8

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

Jura answered 24/6, 2018 at 16:28 Comment(4)
It does give the expected static assertion failure in GCC, which is at least a hint that it could simply be a bug in clang.Knockout
@max66 because operator ++ requires an lvalueGalyak
Yes, beginning to think it's a compiler bug. GCC does seem to do the right thing.Jura
Yeah this seems to be a bug. If you remove the reference from declval it works for me though.Imide
I
1

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

Idiopathy answered 24/10, 2021 at 13:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.