tuple_cat
tuple_cat

Reputation: 1340

Is there any workaround for MSVC producing `Internal compiler error` for this code?

For some reason the below code gives me fatal error C1001: Internal compiler error. with MSVC 19.27, but not with Clang. Any idea how to write it so that the static_assert can be done also on MSVC?

template <typename T, int N, typename K, int M>
constexpr int countIdentifersNotInArray(const T(&identifiers)[N], const K(&array)[M]) {

 auto find = [&array](const unsigned char value) {
        for (const auto& a : array) {
            if (a == value) {
                return true;
            }
        }
        return false;
    };

    int count = 0;
    for (const auto& value : identifiers) {
        if (!find(value)) {
            ++count;
        }
    }
    return count;
}

constexpr bool testIt() {
    return countIdentifersNotInArray({ 0x01, 0x02 }, { 0x01 });
}


int main() {
    static_assert(testIt());
    return 0;
}

I would like to use this in a an environment where stl is not available, so solutions without that are most interesting.

Upvotes: 0

Views: 219

Answers (1)

Joel Filho
Joel Filho

Reputation: 1300

As the comment has pointed out, this is an MSVC bug and you should definitely report to Microsoft.

By removing multiple lines until it stops crashing the compiler, I believe the cause is the range-for loops. So, since they're arrays with known size, you can workaround with the classic indexed loops:

template <typename T, int N, typename K, int M>
constexpr int countIdentifersNotInArray(const T(&identifiers)[N], const K(&array)[M]) {

    auto find = [&array](const auto value) {
        for (int i = 0; i < M; i++) {
            if (array[i] == value) {
                return true;
            }
        }
        return false;
    };

    int count = 0;
    for (int i = 0; i < N; i++) {
        if (!find(identifiers[i])) {
            ++count;
        }
    }
    return count;
}

It works on MSVC.

Upvotes: 2

Related Questions