aantron / better-enums

C++ compile-time enum to string, iteration, in a single header file
http://aantron.github.io/better-enums
BSD 2-Clause "Simplified" License
1.65k stars 172 forks source link

constexpr not working in Visual Studio 2017? #53

Closed dgant closed 5 years ago

dgant commented 6 years ago

Hello @aantron & co.,

Trying to compile with BETTER_ENUM in Visual Studio 2017 produces the following error:

E0028 expression must have a constant value attempt to access run-time storage

The error occurs at the assignment of _value_array.

Here are a few test cases of the compiler behavior:

    //These compile
    constexpr const int example0[] = {
      123
    };
    constexpr const MyEnum example1[] = {
      MyEnum::MyEnumValue
    };
    constexpr const int myEnumValue = MyEnum::MyEnumValue;
    constexpr const int example2[] = {
      myEnumValue
    };    

    //These array assignments all produce error E0028
    constexpr const MyEnum example3[] = {
      ((::better_enums::_eat_assign<MyEnum>)MyEnum::MyEnumValue = 0)
    };
    constexpr const MyEnum example4[] = {
      ::better_enums::_eat_assign<MyEnum>(MyEnum::MyEnumValue)
    };
    constexpr ::better_enums::_eat_assign<MyEnum> myEat(MyEnum::MyEnumValue);
    constexpr const MyEnum example5[] = {
      myEat
    };

This is in Visual Studio 2017 (v15.4.5), and happens using any of the ISO C++14, ISO C++17, and Latest Draft compilers.

I know this is intended to work (apropos the recent commit to support constexpr in VS2017). What's likely to be the issue?

❤️ , dan

aantron commented 6 years ago

Hi @dgant, thanks for reporting that.

I have trouble investigating it myself, as I don't have access to VS2017 at the moment, and I don't see the problem immediately. I would suggest pasting the definition of _eat_assign out into your own file, and trying to narrow down the problem by tweaking it, since _eat_assign looks, at this point, to be the most likely culprit. I'm sure you've already found it, but here is a permalink:

https://github.com/aantron/better-enums/blob/2fad3f60eea97cf3b75339a1562ab13d5e0cc4f7/enum.h#L361-L374

dgant commented 6 years ago

Thanks. VS2017 doesn't mind _eat_assign as a constexpr. For example: constexpr ::better_enums::_eat_assign<MyEnum> myEat(MyEnum::MyEnumValue); compiles. I've also tried implementing my own stripped-down version of EatAssign which removes the templating and such. It seems to be the specific case of initializing a constexpr array with statements that undergo _eat_assign's conversion back to the EnumType.

aantron commented 6 years ago

So, effectively, operator EnumType () is not constexpr? I hope it's not yet another compiler bug.

butterfly20 commented 6 years ago

Hello, I have the same problem in using BETTER_ENUM. Im using Visual Studio 2017 on Windows. Did you find a way how to fix the error?

aantron commented 6 years ago

@butterfly20 As far as I know, no, because we haven't fully diagnosed it (as far as I can tell). I would be happy to help you navigate/strip down the code to figure out what's going on, but otherwise, I think this remains unresolved :/

aantron commented 6 years ago

It may also be possible to work around this by disabling constexpr support in Better Enums. To do this, define BETTER_ENUMS_NO_CONSTEXPR before including enum.h (probably best done on the command line).

butterfly20 commented 6 years ago

Hey,

Thank you so much, that helps me :)

2018-04-09 18:16 GMT+02:00 Anton Bachin notifications@github.com:

It may also be possible to work around this by disabling constexpr support in Better Enums. To do this, define BETTER_ENUMS_NO_CONSTEXPR before including enum.h (probably best done on the command line).

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/aantron/better-enums/issues/53#issuecomment-379808330, or mute the thread https://github.com/notifications/unsubscribe-auth/Ad07aEwbvO0VqfS7_O9RDn7Q1tO1Hy_4ks5tm4lQgaJpZM4Q-zQr .

-- Kind regards, Feryel Zoghlami

D4koon commented 5 years ago

I tried to fix it (may not work for compilers != VS17): Fix for VS17

Image of the error: enumerror Image where the error is no longer there: enumerrorfixed

I don't know if this breaks anything but so far it seems to work. Not sure what the cast is for :D, It seems to work fine without. Also i noticed that it compiles fine even with the error. Seems to be some intellisens problem. But having an error in the project is still not what i want...

aantron commented 5 years ago

@D4koon If you don't mind submitting your fix as a PR, the CI should be able to say if it works for other versions of the compiler.

aantron commented 5 years ago

I believe this was fixed by @D4koon in #70. I haven't checked myself due to not having VS2017 installed, so please feel free to reopen if it needs further work. Thanks @D4koon!