0

I'm compiling my code in Arduino IDE. I have an array that I want to 0-initialize. I know memset works on Arduino, but I'm used to this way from my desktop C++ programming practice:

int array[100] = {0};

I couldn't find any info on whether or not this construct works on Arduino. I think it should since it uses GCC compiler. Even though it may be modified, I still expect it to remain C and C++-compliant. Still, can you confirm for me that this standard-compliant C/C++ construct works on Arduino?

10
  • 2
    Have you tried it? What were the results?
    – Majenko
    Feb 26, 2017 at 14:15
  • @Majenko: It seems to: the program is much larger with = {0} that without it, so the compiler is definitely doing something. On the other hand, in my test the array was all 0s both with and without = {0}. Problem is, that proves nothing. It doesn't guarantee that it will work on some other compiler with some other settings. The testing would only be conclusive if it demonstrated that this code does not work. Feb 26, 2017 at 14:23
  • It's not the compiler that does it (and the = {0} does nothing by the way) but the CRT (initialization code). Maybe this will explain: en.wikipedia.org/wiki/.bss
    – Majenko
    Feb 26, 2017 at 14:28
  • @Majenko: a) if it does nothing then Arduino IDE compiler is broken: stackoverflow.com/a/629063/634821 b) how does it do nothing when it increases code size by a couple hundred bytes? Feb 26, 2017 at 14:33
  • 1
    You should start from the premise that the Arduino uses standard C++ (however exceptions are disabled by a command-line switch). If something is standard C++ then it will work. You don't need to worry about proving it.
    – Nick Gammon
    Mar 10, 2017 at 0:51

3 Answers 3

4

I'm used to this way from my desktop C++ programming practice:

int array[100] = {0};

I couldn't find any info on whether or not this construct works on Arduino.

The = {0} has no actual effect. It is the same as:

int array[100];

Uninitialized static / global variables, and variables explicitly initialized to 0, are placed in the .bss section of memory.

This section is initialized to 0 by the CRT (C Runtime) code (the startup code for the system).

The compiler is responsible for placing these variables in the .bss, but it is the job of the startup (CRT) code to initialize it to zero.

This is standard C operation and is not likely to ever change since it would break all sorts of things.

Note: this does NOT apply to local variables allocated on the stack. These must be initialized to 0 if you want them to start as 0.

1
  • Very well, thanks for the explanation. I have no habit of relying on C default-initializing POD types (because it usually doesn't) and hence prefer doing it explicitly, but then, I also have no habit of using global or static data a lot. Didn't know the global variables are guaranteed to be default initialized (or zero-initialized? I always confuse these two terms). The main point of = {0} is that it also works for local arrays. Feb 26, 2017 at 14:45
5

This construct does work in Arduino IDE. In fact, = { 0 } is one of the iconic idioms of C language. It can be used to zero-initialize an object of any type in C. In C++ things are a bit more complicated. It will work for an int [100] array, but in general case you might be better off with = {} initializer to achieve the same effect where applicable.

It is not clear why the accepted answer claims that this construct "has no actual effect" though. This is, of course, incorrect. More precisely, this initializer is redundant ("has no effect") on variables with static storage duration, since such variables are default-initialized anyway (zero-initialized for int [100]), even if you don't request it explicitly. But for a local variable declaration the effect of = { 0 } is undeniable and obvious: it will zero-initialize the array (which wouldn't've been initialized without it).

Note that even though the 0 in the = { 0 } initializes the first element of the array, this initializer ultimately triggers zero-initialization if the entire array.

4

The GNU cross compilers for Arduino use C/C++ front-ends and meet some version the language specs. (Although that is a moving target, you can expect a recent IDE version will be compliant with a reasonably recent language spec.)

"Arduino language" is a misnomer. The Arduino IDE will try to assist new programmers by, for example, automagically discovering library references and inserting the required #includes for you, but the resulting code is C++ and will be presented to a C++ compiler. The IDE provides a main() function that calls setup() and loop() (and serialEventRun() if you provide one) thereby reminding the programmer to initialize whatever needs to be initialized before expecting things to work right. However you can write proper C++ and get what you've come to expect. You'd have to go 'behind the IDE's back' as it were, to suppress the automatically-supplied main() function, but the toolchain doesn't care, as long as there is one and only one, main().

I tested this this trivial program:

    int array[100];

    void setup() {
      // put your setup code here, to run once:
       for(uint8_t i = 0; i < sizeof(array); ++i)
          array[i] = i;
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
    
    }

with both the Arduino IDE and Sloeber - Eclipse with the EclipseArduino plugin, which routinely provides a basic memory map after compilation - and with and without the initialization expression = {0}. I found no difference in the size of the output in either environment, with or without the initialization. In all four cases, the .bss was 209 bytes, 200 bytes larger than without the global array.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.