Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GCC: why constant variables not placed in .rodata

I've always believed that GCC would place a static const variable to .rodata segments (or to .text segments for optimizations) of an ELF or such file. But it seems not that case.

I'm currently using gcc (GCC) 4.7.0 20120505 (prerelease) on a laptop with GNU/Linux. And it does place a static constant variable to .bss segment:

/*  * this is a.c, and in its generated asm file a.s, the following line gives:  *   .comm a,4,4   * which would place variable a in .bss but not .rodata(or .text)  */ static const int a;  int main() {     int *p = (int*)&a;     *p = 0;  /* since a is in .data, write access to that region */              /* won't trigger an exception */     return 0; } 

So, is this a bug or a feature? I've decided to file this as a bug to bugzilla but it might be better to ask for help first.

Are there any reasons that GCC can't place a const variable in .rodata?

UPDATED:

As tested, a constant variable with an explicit initialization(like const int a = 0;) would be placed into .rodata by GCC, while I left the variable uninitialized. Thus this question might be closed later -- I didn't present a correct question maybe.

Also, in my previous words I wrote that the variable a is placed in '.data' section, which is incorrect. It's actually placed into .bss section since not initialized. Text above now is corrected.

like image 888
starrify Avatar asked May 30 '12 14:05

starrify


People also ask

Do constant variables need to be initialized?

A constant variable must be initialized at its declaration. To declare a constant variable in C++, the keyword const is written before the variable's data type. Constant variables can be declared for any data types, such as int , double , char , or string .

What is stored in Rodata?

rodata), which contains static constants rather than variables; it also contrasts to the code segment, also known as the text segment, which is read-only on many architectures. Uninitialized data, both variables and constants, is instead in the BSS segment.


1 Answers

The compiler has made it a common, which can be merged with other compatible symbols, and which can go in bss (taking no space on disk) if it ends up with no explicitly initialized definition. Putting it in rodata would be a trade-off; you'd save memory (commit charge) at runtime, but would use more space on disk (potentially a lot for a huge array).

If you'd rather it go in rodata, use the -fno-common option to GCC.

like image 57
R.. GitHub STOP HELPING ICE Avatar answered Sep 28 '22 11:09

R.. GitHub STOP HELPING ICE