[BUG] Initializing an enum array does not compile
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
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
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 Yes, but what's the solution to my issue? It doesn't seem to be related to my problem.
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.
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.
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).
Ah yes indeed, thank you 😊
@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:
That out this parameter is missing that implicit keyword above.
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: