Jonathan Mee
Jonathan Mee

Reputation: 38969

Work around disregarded constexpr in Visual Studio?

I have this code:

constexpr int log2(const unsigned int x) {
    return x < 4 ? 1 : 1 + log2(x / 2);
}

int main() {
    bitset<log2(2)> foo;
    int bar[log2(8)];

    cout << log2(8) << endl;
}

This works fine in gcc: https://ideone.com/KooxoS

But when I try on I get these errors:

error C2975: _Bits: invalid template argument for std::bitset, expected compile-time constant expression
note: see declaration of _Bits
error C2131: expression did not evaluate to a constant
note: failure was caused by call of undefined function or one not declared constexpr
note: see usage of log2

Obviously log2 is constexpr so I assume this is just a bug in . Is there a way I can work around this bug?

Upvotes: 2

Views: 1125

Answers (2)

Fran&#231;ois Andrieux
Fran&#231;ois Andrieux

Reputation: 29072

It looks like your project includes the standard std::log2 function which the compiler confuses with the your log2 function. This can happen even if you don't #include <cmath> because standard headers are allowed to include any other standard headers. This is also another example of using namespace std; backfiring.

One solution is to rename your constexpr function to something else :

#include <bitset>
#include <iostream>

using namespace std;

constexpr int logTwo(const unsigned int x) {
    return x < 4 ? 1 : 1 + logTwo(x / 2);
}

int main() {
    bitset<logTwo(2)> foo;
    int bar[logTwo(8)];

    cout << logTwo(8) << endl;
}

Demo

Edit : It seems that using namespace std; may be unrelated in this case. The standard log2 function may be available at the global namespace anyway.

Upvotes: 5

Acorn
Acorn

Reputation: 26194

Obviously log2 is constexpr

A function being constexpr does not mean it can be always used to compute a compute-time value. When x >= 4, you are calling std::log2, which is not constexpr itself.

GCC implements them as such as an extension. See Is it a conforming compiler extension to treat non-constexpr standard library functions as constexpr?

Upvotes: 3

Related Questions