Buffer exceeding ramsize do not produce error in avr-gcc

In my source code I have tried to allocate a huge buffer exceeding the RAMSIZE value (RAM of my component (ATmega324PB) is 2k).

volatile char buffer[4000];


This buffer is in bss section. What I understand is that both data and bss goes to RAM. So it is not possible to do that. But I have no error of avr-gcc (gcc version 5.4.0 (GCC)).

I checked RAMSIZE value in iom324pb.h, but it seems ok.

The error only occurs if I exceed 32767 bytes.

Why not having an error here with a 4000 bytes buffer ?

(NB: compilation and upload works, but not execution).

• I would imagine the compiler is just optimising it out. Volatile will not protect you from this (if nowhere in your code uses it, your program can ignore it). Try writing some values into it at run time and see what happens.
– Jon
Jan 25 '20 at 13:24
• volatile keyword is not here to try to saves my life. It is just here because I need it in my code so write also here. It is the same without the keyword. And as written, the code does not run at all. So can't look at what is done.
– doom
Jan 25 '20 at 13:42

It is not the header, but the linker script that specifies the sizes of various memories. In the gcc world it usually ends with .ld. Example from the Cortex-M world (AVR should be similar):

MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 65536
RAM (rwx)  : ORIGIN = 0x20000000, LENGTH = 8192
}


If the data+bss size is bigger than the RAM section you would get a linker error (assuming that the big array is not optimized out).

• Sure. But avr-gcc seems to be also the linker. Can you please tell me where is it located this file (sorry but I did not found it) ?
– doom
Jan 27 '20 at 10:36

You would expect the error to occur at link time, not compile time.

The compiler cares about instruction sets and to some extent what sections are called, but the question of exactly where data goes is a problem for the linker.

The linker reads a 'linker script' that should be specific to the memory layout of the part in question and uses this to decide where to put things. It is what should complain if you run out of space for a section. The linker can generate a thing called a 'map file' that details exactly where it has located each variable, and examination of this may give insights into what is going on.

In general, the compiler doesn’t know exactly what device you’re running on, just the CPU architecture. This is so that you don’t have to recompile for every possible device. The compiler doesn’t know you don’t have 4K of RAM, so it won’t flag an error for it.

Even though the compiler doesn’t do it, it’s possible to make this sort of check prior to runtime. The Arduino development environment, for example, reads the “link map” — a description of where code and static data will be placed in memory — after the program is built, and compares it against the memory map of the specific device you’re using, and will tell you if it doesn’t fit.

• avr-gcc knows the device I use : avr-gcc -I. -I/path/to/include -g -mmcu=atmega324pb -Os -fpack-struct -fshort-enums -funsigned-bitfields -funsigned-char -Wall -Wa,-ahlms=main.lst -Wstrict-prototypes -c main.c -o main.o
– doom
Jan 25 '20 at 20:31
• I believe the compiler only uses that information to determine what instruction set and architectural features are available, but I could be mistaken. Jan 25 '20 at 21:03
• OK, maybe. But I am pretty sure AVR Studio raises the error. So how ?
– doom
Jan 25 '20 at 21:11