cppfront icon indicating copy to clipboard operation
cppfront copied to clipboard

[BUG] Initializing an enum array does not compile

Open MatthieuHernandez opened this issue 1 year ago • 10 comments

I try to compile this simple code:

Color: @enum<u8> type = {
    Black: = 0;
    White: = 1;
}
main: () = {
    colors: std::array<Color, 3> = (Color::Black);
}

The C++ code is generated correctly but I get an error when compiling.

main.cpp2:6:40: error: chosen constructor is explicit in copy-initialization
    6 |     std::array<Color,3> colors {Color::Black}; 
      |                                        ^~~~~
main.cpp2:12:18: note: explicit constructor declared here
   12 | constexpr Color::Color()
      |                  ^
main.cpp2:6:40: note: in implicit initialization of array element 1 with omitted initializer
    6 |     std::array<Color,3> colors {Color::Black}; 
      |                                        ^
1 error generated.

Here is the code I ran: https://cpp2.godbolt.org/z/MnrPqT4fK

MatthieuHernandez avatar Oct 12 '24 00:10 MatthieuHernandez

I'm wondering if something really breaking has happened lately. I can't even get the hello world example to compile either.

https://cpp2.godbolt.org/z/3n3YW5rdW

gregerolsson avatar Oct 12 '24 14:10 gregerolsson

Yes. Commit 2c03e416bf3ceb1d2f94f148fc026e4de490b242 happened, which made single-expression functions be not order independent. Add { } around its body, and it compiles again: https://cpp2.godbolt.org/z/j55sP1soo.

JohelEGP avatar Oct 12 '24 14:10 JohelEGP

@JohelEGP Yes, but what's the solution to my issue? It doesn't seem to be related to my problem.

MatthieuHernandez avatar Oct 12 '24 21:10 MatthieuHernandez

If you add @print after, you'll see that it has this (https://cpp2.godbolt.org/z/P6TYxEasK):

    operator=:(out this, ) == 
    {
        _value = Black._value;
    }

If you attempt to add an implicit default constructor, e.g. (https://cpp2.godbolt.org/z/hqonP3dbG):

    operator=: (implicit out this) = {
         this = Black;
    }

It'll fail with:

main.cpp2(4,5): error: while applying @enum - in a 'enum' type, the name 'operator=' is reserved for use by the 'enum' implementation

If you want to use @enum with std::array like that, then @enum will need to emit an implicit default constructor, or allow the user to write one.

JohelEGP avatar Oct 12 '24 21:10 JohelEGP

Yes, cpp2 enum should have a default constructor. I'd like to contribute to the cppfront project but I'm not sure where to start, the code is a little difficult to grasp.

MatthieuHernandez avatar Oct 12 '24 22:10 MatthieuHernandez

Oh, but it does have a default constructor, it's just explicit. So this works: colors: std::array<Color, 3> = (Color(), Color(), Color()); (https://cpp2.godbolt.org/z/9Wrj8qKd8).

JohelEGP avatar Oct 12 '24 22:10 JohelEGP

Ah yes indeed, thank you 😊

MatthieuHernandez avatar Oct 12 '24 22:10 MatthieuHernandez

@JohelEGP In fact, I have the same problem with any objects, if I redefine the constructor. I feel like there's no way to write this or an equivalent:

Color: type = {
    value: i32 = 0;

    operator=:(out this) = {
        value++;
    }
}
main: () = {
    colors: std::array<Color, 1000> = ();
    std::cout << Color[999].value << std::endl;
}

This colors: std::array<Color, 1000> = (); required an implicit constructor on Color that isn't possible for now. And this colors: std::array<Color, 1000>; prodce this error program violates initialization safety guarantee which seems normal.

But my conclusion is that for the moment it's impossible to declare an array of 1000 objects without writing them all one by one. So to keep on progressing on my project I'll have to use std::vector instead of std::array.

Please feel free to correct me if I'm talking nonsense :sweat_smile:

MatthieuHernandez avatar Oct 18 '24 23:10 MatthieuHernandez

That out this parameter is missing that implicit keyword above.

JohelEGP avatar Oct 19 '24 00:10 JohelEGP

Oh yes, sorry, I didn't realize that implicit keyword existed in cpp2. I totally missed it when I looked at the documentation. Now everything is working properly, I spent so much time pulling my hair out for nothing :grin:

MatthieuHernandez avatar Oct 19 '24 13:10 MatthieuHernandez