5

GCC G++ 9

This code:

   class foo {
     int bar[] = {111, 123};
   };

produces an error about initializer for flexible array. But this one:

   class foo {
     int bar[2] = {111, 123};
   };

compiles as normal. Any workaround for not counting the values I put in?

tohaz
  • 197
  • 5
  • 19
  • 3
    Hint: `std::vector`. C++ needs to know the exact size of a structure in advance. You can't make it up as you go. – tadman Jan 08 '20 at 21:47
  • 4
    No, no workarounds. C++ just doesn't work this way. – Sam Varshavchik Jan 08 '20 at 21:47
  • std::vector suits well for my usecase as i tested. it supports [] notation and does not want me to specify array size. i was aware of it, just i was not prepared that flexible array would be of a problem. thanks!!! :) – tohaz Jan 08 '20 at 22:11
  • There is no such thing as flexible array member in C++ – Slava Jan 08 '20 at 22:24
  • @Slava Doesn't `static constexpr int bar[] = {111, 123};` count as a flexible array member? It's probably unusable for OP, but still. – Ted Lyngmo Jan 08 '20 at 22:44
  • @tadman There is no boost library on an Arduino. Sometimes libraries can't replace missing language features. – Martin Nov 05 '20 at 17:19
  • 1
    @Martin This isn't Boost, it's in the C++ Standard Library. If that's not an option for *reasons* then that needs to be specified in the question as that's an edge case. – tadman Nov 05 '20 at 21:18

1 Answers1

6

Unlike in a function where you can do

int foo[] = { 1, 2, 3 };

and the compiler will deduce the size of foo from the initializer, when you do

struct bar
{
    int foo[] = { 1, 2, 3 };
};

what you really have is

struct bar
{
    bar() : foo{ 1, 2, 3 } {}
    int foo[];
};

and that can't work because C++ does not allow flexible arrays like C does.

That leaves you with two options. The first is you specify the size. This isn't the greatest solution since it could introduce bugs but it will save you from dynamic initialization. The second option is to use a type that, at run time, can be initialized from the list. A std::vector for instance would fill that requirement nicely. Yes, there will be a dynamic memory allocation, but since std::vector is an RAII type, you don't need to worry about it and can use the default constructors and destructor.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • 1
    If a fixed size array is wanted, `std::array` would be also appropriate. – n314159 Jan 08 '20 at 21:57
  • 1
    @tohaz It's a great container. It's my go-to unless I can use a `std::array` – NathanOliver Jan 08 '20 at 22:13
  • 1
    For `std::array` (without having to count the values) I guess something like `static constexpr std::array init = {111, 123}; std::remove_const_t bar = init;` could be an option. – Ted Lyngmo Jan 08 '20 at 22:15
  • 1
    Of course all the `std::…` solutions won't help if the target device is an Arduino where there is no boost library. Sometimes libraries can't make up for lack of language functionality. – Martin Nov 05 '20 at 17:17