GCC warns about out-of-bound issues like this. Compiling this code example with -Wall -pedantic -O1
:
int main(void) {
int example[50];
for (int i = 0; i < 100; i++)
example[i] = i;
return example[0];
}
...results in this compilation warning (using ARM GCC 11.2 (linux), testable here on Godbolt, like already pointed out in the comments of Tom V's answer):
<source>: In function 'main':
<source>:4:20: warning: iteration 50 invokes undefined behavior [-Waggressive-loop-optimizations]
4 | example[i] = i;
| ~~~~~~~~~~~^~~
<source>:3:23: note: within this loop
3 | for (int i = 0; i < 100; i++)
| ~~^~~~~
Compiler returned: 0
In this case, the optimization option flag -O1
(or -O2
, -Os
) is required to get the undefined behavior warning from GCC. -O3
optimizes the loop out, so there will be no warning. No optimization (default option -O0
) also results in no warning, because GCC apparently only notices the out-of-bound issue when it's optimizing the loop (see -Waggressive-loop-optimizations
), as far as I can tell.
(Some notes:
GCC's -fstack-check
and -fstack-protector
options might also be worth a look (runtime checks). Valgrind or other static/dynamic analysis tools can also be useful. However, on microcontrollers it is often not that easy to analyze the program at runtime on the target, an emulator or compiling the non-platform specific parts of the program with different compilers right on the development machine can help as well, to make it more rigid.
Related topics have been discussed here: Accessing an array out of bounds gives no error, why?, How does the gcc option -fstack-check exactly work?)