C语言静态/全局变量数据段内存分配异常问题咨询
Great question—this is a perfect example of how theoretical memory segment behavior collides with real-world compiler and linker optimizations. Let’s walk through your test cases and unpack the unexpected results step by step:
First, let’s recap your setup and the size output you observed:
text data bss dec hex filename
1217 560 8 1785 6f9 segment_size1
1217 560 8 1785 6f9 segment_size2
1217 564 12 1793 701 segment_size3
1217 564 12 1793 701 segment_size4
1217 568 16 1801 709 segment_size5
1. Why didn’t segment_size2’s BSS grow?
You added an uninitialized static variable static int mystatic; here, but modern compilers (like GCC) enable dead data elimination by default. Since this variable is never read or written anywhere in the code, the compiler and linker treat it as "garbage" and strip it out of the final executable. That’s why the BSS size stayed identical to segment_size1—your unused static variable never made it into the segment at all.
2. Why did both Data and BSS grow in segment_size3?
Here you added static int mystatic1 = 100; (an initialized static variable) alongside the existing uninitialized mystatic:
- The Data segment grew by 4 bytes as expected: this is the space for
mystatic1, since initialized static variables live in the Data segment. - The BSS segment also grew by 4 bytes because the uninitialized
mystaticwasn’t optimized away this time. Compilers are often more conservative about removing uninitialized variables when they’re in the same compile unit as an initialized variable that’s being retained. Sincemystatic1was kept (likely because it has an explicit initializer),mystaticgot pulled along with it into the BSS segment.
3. Why is segment_size4 identical to segment_size3?
You added an uninitialized global variable int myglobal;, but again—this variable is never used. The linker’s garbage collection optimization stripped it out, so the BSS size didn’t increase further. This makes sense once you understand the optimization behavior at play.
4. Why did both segments grow again in segment_size5?
You added an initialized global variable int myglobal2 = 500;, which got added to the Data segment (hence the 4-byte increase). This time, the uninitialized global myglobal wasn’t optimized away—similar to the static variable case, having an initialized global in the same compile unit made the linker retain the uninitialized one, adding another 4 bytes to the BSS segment.
How to Get Your Expected Behavior
If you want to see the segments grow exactly as you initially predicted, disable the garbage collection optimizations during compilation:
gcc -fno-data-sections -Wl,--no-gc-sections your_file.c -o your_file
This tells the compiler not to split data into separate sections and the linker not to strip unused sections. Run size on the resulting executable, and you’ll see BSS/Data grow by 4 bytes exactly when you add uninitialized/initialized variables—even if they’re unused.
You can also verify which variables are present using the nm command:
nm segment_size2 | grep mystatic
With default optimizations, this won’t return anything (the variable was stripped). With optimizations disabled, you’ll see the mystatic symbol listed in the BSS section.
内容的提问来源于stack exchange,提问作者pratik

