ESP32 (vs. AVR) size of char arrays

with an Arduino Nano (ATMega) the following will compile and work as expected (by me at least):

#define TEST_CHARS "ABC"
char test[3] = TEST_CHARS;

When I sue the same on an Arduino Nano ESP32 I get an compiler error:

C:\Users\Admin\AppData\Local\Temp.arduinoIDE-unsaved2024813-8916-toqsxg.anrul\Blink\Blink.ino:25:20: error: initializer-string for array of chars is too long [-fpermissive]
#define TEST_CHARS "ABC"
^~~~~
C:\Users\Admin\AppData\Local\Temp.arduinoIDE-unsaved2024813-8916-toqsxg.anrul\Blink\Blink.ino:27:16: note: in expansion of macro 'TEST_CHARS'
char test[3] = TEST_CHARS;
^~~~~~~~~~

exit status 1

Compilation error: initializer-string for array of chars is too long [-fpermissive]

If I change the code to the following:

#define TEST_CHARS "ABC"
char test[3 +1] = TEST_CHARS;

it will compile for the ESP32.
My guess is that show a \0 get added to the constants?
But why and is there any way to avoid this?

TIA, Ingo

A tad odd i admit, but i am sure that

char test[3] = {'A', 'B', 'C'};

does compile

That's because the compiler for AVR-based processors has the [-fpermissive] flag set so it lets you do stupid things. The settings for the ESP32's processor are more rigorous.

A c-string link you're trying do define has a null terminator on the end. So your array needs 4 bytes (regardless of processor). But, why are you putting a number there at all, let the compiler do it for you:

#define TEST_CHARS "ABC"

char test[] = TEST_CHARS;

void setup() {
}

void loop() {

}

And that will give you an array of 3 characters, not a c-string. It will cause any of the c-string functions to blow up.

That may be what you want though. a character array is a an array, and does not always equal a c-string.

An array of 3 characters is exactly what I want, however.
I do not have any intention of using string functions on this.

The only drawback to the {'A', 'B', 'C'} solution is that the defines come from a header file that is generated by an excel file and I would have to change the VBA code.

But using a null-terminator in the char arrays became a standard and you should admit it. Adding a single extra array element to your VBA code would be a most correct solution.

Trouble is, "ABC" is a string literal. So, if used in initialization, the compiler will try to create a c-string from it.

Trouble is, "ABC" is a string literal. So, if used in initialization, the compiler will try to create a c-string from it.

Yes, this is what I overlooked.
I wrongly assumed that as long as it was not assigned to "anything string" it would just behave like an "array of char".
As I would like to stay with char[3] (the 3 chars will only be used for comparison to another char[3] - this is all part of a look-up table) I will use a macro to split the string literal:

#define CHARS_FROM_STRING3(str) {str[0], str[1], str[2]}
#define TEST_CHARS "ABC"
char test[3] = CHARS_FROM_STRING3(TEST_CHARS);

Thanks to ewverybody for answering!

Kind of ugly. Why don't you just let it be a 4-byte array ending in the null terminator and ignore the last byte?

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.