Odd error initializing array - any ideas?

I've built a library/class which is working fairly well. I've come across this oddity:

To my understanding, C++ array initialization is done like this:
rpmSpeed[] {1,2,3,4,5};

In the .h file of the library, an array is declared as private:
rpmSpeed[5];

Whenever I've used the above syntax, the Arduino compiler complains. Nor does it like it initialized in the .h file
and if I try and use that syntax in the constructor, it still produces errors. I have to resort to this in the class constructor:

rpmSpeed[0] = 300000;
rpmSpeed[1] = 150000;
rpmSpeed[2] = 75000;
rpmSpeed[3] = 37500;
rpmSpeed[4] = 18750;

This compiles and works as expected.

Any ideas why the usual '{}' init syntax is failing? :fearful:

o my understanding, C++ array initialization is done like this:
rpmSpeed[] {1,2,3,4,5};

You're missing "="

rpmSpeed[] = {1,2,3,4,5};

If you mean something like this:

char someArray[5];

void setup(){
  someArray = {1,2,3,4,5};
}

Then it is not allowed - you can't assign one array to another.

What you can do though is this:

char someArray[5];

void setup(){
  const char initArray[sizeof(someArray)/sizeof(someArray[0])] = {1,2,3,4,5};
  memcpy(someArray,initArray,sizeof(someArray)); //fill someArray with the contents of the init array
}

(p.s. you can use numbers instead of sizeof(), but the latter is safer in case you change something later).

You cannot do this

char rpm[5] ;
char rpm[]={'1' , '2' , '3' , '4' , '5'  }  ;

because that is defining the variable twice.

Just use the second line and get rid of the first line.

The array declaration and initialization in one step syntax ONLY works when the declaration and initialization are done using one statement. Since you can't declare and initialize the array in the header file, the declaration and initialization need to be separated. You can't use the initialization portion of the syntax by itself in the source file. One element at a time is the only way.

So? What would be the best way to do this?

My first thought is to declare an array of constants in the header just before the class. Then assigning those values in the constructor.

const byte RPM_COUNT = 5;
const unsigned long RPMS[RPM_COUNT] = { 300000, 150000, 75000, 37500, 18750 };

class myClass{
    unsigned long rpmSpeed[RPM_COUNT];

public :

    myClass(void) { for (byte i = 0; i < RPM_COUNT; i++) rpmSpeed[i] = RPMS[i]; }
};

Is that a good approach or are there better ways?

Jimmy60:
Is that a good approach or are there better ways?

See reply #2 and modify it to suit.

Why would that be a better approach?

I'm going to go play with it in the mean time.

It may or may not be, just an alternative method.

Edit:
Just tested the two and it makes no real difference for small arrays, but for long arrays mine may use less flash space or it may not, who knows.

That would coincide with what I just found. Your method used less flash but more ram.

I used these two sketches. I think I translated your approach correctly. It took some looking, turns out it wasn't a big change. I did skip the sizeof() bits.

Sketch 1

const byte RPM_COUNT = 5;
const unsigned long RPMS[RPM_COUNT] = { 300000, 150000, 75000, 37500, 18750 };

class myClass{
    unsigned long rpmSpeed[RPM_COUNT];

public :

    myClass(void) { for (byte i = 0; i < RPM_COUNT; i++) rpmSpeed[i] = RPMS[i]; }
};

myClass object;
void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

Sketch 1 compile results:
Sketch uses 624 bytes (1%) of program storage space. Maximum is 32,256 bytes.
Global variables use 29 bytes (1%) of dynamic memory, leaving 2,019 bytes for local variables. Maximum is 2,048 bytes.

Sketch 2

const byte RPM_COUNT = 5;
const unsigned long RPMS[RPM_COUNT] = { 300000, 150000, 75000, 37500, 18750 };

class myClass {
    unsigned long rpmSpeed[RPM_COUNT];

  public :

    myClass(void) { memcpy(rpmSpeed, RPMS, RPM_COUNT); }
};

myClass object;
void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

Sketch 2 compile results:
Sketch uses 542 bytes (1%) of program storage space. Maximum is 32,256 bytes.
Global variables use 49 bytes (2%) of dynamic memory, leaving 1,999 bytes for local variables. Maximum is 2,048 bytes.

I wonder why the extra 20 bytes?

So I changed the array size to 10 (and 100) and they both use the same ram. Flash use with memcpy() was still lower.

memcpy() wins except maybe for smaller arrays.

By the way, thanks.

As it turns out you CAN leave out the '=' sign - found that piece 'o c-lore on some c++ info site.

=A.

AWOL:

o my understanding, C++ array initialization is done like this:
rpmSpeed[] {1,2,3,4,5};

You're missing "="

rpmSpeed[] = {1,2,3,4,5};

As it turns out you CAN leave out the '=' sign

How's that working for you?