'How does .rodata occupy ROM space? [closed]

I'm using esp32c3(a riscv architecture chip). I use a global string array initialized with string, and it occupies ram and rom. When I add "const" keyword before the array, the array is put into .rodata by link script. Then I found that the ram consumption reduces(this is in line with my expectation). However, the compiled .bin firmware file size is reduced. I think even if the const keyword is added to the array, the size of the compiled .bin firmware file should remain unchanged, because the strings are always need to be stored in the firmware.This puzzles me.

Other info: If a pointer is used to point to the same string content(instead of using string array, and the pointer is is located at .sdata), the .bin file size will increase, ram consumption not increase.

At the same time, I saw this paragraph in the official data of the chip, but I didn't fully understand the meaning:

By default, constant data is placed by the linker into a region mapped to the MMU flash cache. This is the same as the IROM (code executed from flash) section, but is for read-only data not executable code. The only constant data not placed into this memory type by default are literal constants which are embedded by the compiler into application code. These are placed as the surrounding function’s executable instructions.



Solution 1:[1]

You don't specify it in your question, but I'm assuming your array is initialized with some non-zero data.

Your typical executable will look something like this [source]:

ELF file

When you add the const keyword, the array simply gets moved from the .data section into the .rodata. The net change in file size is 0.

If you also add static keyword to your array, it will be moved into the .text section, but again, the size will remain the same.

See Wikipedia page on Data segment for the information about each section.

Solution 2:[2]

If I get you correct, you expect the following to happen when you add const to your array:

  1. the RAM consumption is reduced
  2. the ROM consumption is increased.

But you can only observe 1), not 2).

Without looking at the exact sections that are used, you are missing one thing:

If you have an array like this:

char myArray[] = "This is the String for my Array!";

Then you need 2 chunks of memory:

  1. RAM area for holding your array
  2. ROM area for holding the string literal you are using to initialized that array.

At startup the initialization string is copied from ROM to RAM area.

If you make the array const, there is no more need to copy the string into RAM and you will see RAM consumption drop. But wrt ROM consumption, there is no big difference as the data is already there.

Therefore ROM area will not be reduced.

Solution 3:[3]

The usual reason is that at the OS level memory gets allocated in fixed sized chunks for reasons owing to the hardware in use, if you add an object to .rodata that doesn't cross a boundary of that size then no more memory will need to be allocated than if that object were not part of the program. I can't tell you anything about the embedded platform you are using but for x86 for example that fixed size will be either 4kb, 2mb or 4mb (that is, the page size).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Armandas
Solution 2 Gerhardh
Solution 3 SoronelHaetir