This article tests the layout memory distribution of C language variables and constants in different situations in the Linux environment.
Architecture:x86_64
Operation system:ubuntu 18.04
edit: gcc 7.4.0
variable
Initialized
The global variable var is initialized to 1:
int var = 1;
int say() {
return var;
}
root@nemo-VirtualBox:~/workspace/learn# gcc -c test.c
root@nemo-VirtualBox:~/workspace/learn# readelf -s -W test.oSymbol table '.symtab' contains 10 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS test.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
3: 0000000000000000 0 SECTION LOCAL DEFAULT 3
4: 0000000000000000 0 SECTION LOCAL DEFAULT 4
5: 0000000000000000 0 SECTION LOCAL DEFAULT 6
6: 0000000000000000 0 SECTION LOCAL DEFAULT 7
7: 0000000000000000 0 SECTION LOCAL DEFAULT 5
8: 0000000000000000 4 OBJECT GLOBAL DEFAULT 3 var
9: 0000000000000000 12 FUNC GLOBAL DEFAULT 1 say
root@nemo-VirtualBox:~/workspace/learn# readelf -S -W test.o
There are 12 section headers, starting at offset 0x248:Section Headers:
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
[ 0] NULL 0000000000000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 0000000000000000 000040 00000c 00 AX 0 0 1
[ 2] .rela.text RELA 0000000000000000 0001b8 000018 18 I 9 1 8
[ 3] .data PROGBITS 0000000000000000 00004c 000004 00 WA 0 0 4
[ 4] .bss NOBITS 0000000000000000 000050 000000 00 WA 0 0 1
[ 5] .comment PROGBITS 0000000000000000 000050 00002c 01 MS 0 0 1
[ 6] .note.GNU-stack PROGBITS 0000000000000000 00007c 000000 00 0 0 1
[ 7] .eh_frame PROGBITS 0000000000000000 000080 000038 00 A 0 0 8
[ 8] .rela.eh_frame RELA 0000000000000000 0001d0 000018 18 I 9 7 8
[ 9] .symtab SYMTAB 0000000000000000 0000b8 0000f0 18 10 8 8
[10] .strtab STRTAB 0000000000000000 0001a8 000010 00 0 0 1
[11] .shstrtab STRTAB 0000000000000000 0001e8 000059 00 0 0 1
int var =1 After compilation, in the .data section of the relocatable object file
The local variable var is initialized to 1:
static int var = 1;
int say() {
return var;
}
root@nemo-VirtualBox:~/workspace/learn# gcc -c test.c
root@nemo-VirtualBox:~/workspace/learn# readelf -s -W test.oSymbol table '.symtab' contains 10 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS test.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
3: 0000000000000000 0 SECTION LOCAL DEFAULT 3
4: 0000000000000000 0 SECTION LOCAL DEFAULT 4
5: 0000000000000000 4 OBJECT LOCAL DEFAULT 3 var
6: 0000000000000000 0 SECTION LOCAL DEFAULT 6
7: 0000000000000000 0 SECTION LOCAL DEFAULT 7
8: 0000000000000000 0 SECTION LOCAL DEFAULT 5
9: 0000000000000000 12 FUNC GLOBAL DEFAULT 1 say
root@nemo-VirtualBox:~/workspace/learn# readelf -S -W test.o
There are 12 section headers, starting at offset 0x248:Section Headers:
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
[ 0] NULL 0000000000000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 0000000000000000 000040 00000c 00 AX 0 0 1
[ 2] .rela.text RELA 0000000000000000 0001b8 000018 18 I 9 1 8
[ 3] .data PROGBITS 0000000000000000 00004c 000004 00 WA 0 0 4
[ 4] .bss NOBITS 0000000000000000 000050 000000 00 WA 0 0 1
[ 5] .comment PROGBITS 0000000000000000 000050 00002c 01 MS 0 0 1
[ 6] .note.GNU-stack PROGBITS 0000000000000000 00007c 000000 00 0 0 1
[ 7] .eh_frame PROGBITS 0000000000000000 000080 000038 00 A 0 0 8
[ 8] .rela.eh_frame RELA 0000000000000000 0001d0 000018 18 I 9 7 8
[ 9] .symtab SYMTAB 0000000000000000 0000b8 0000f0 18 10 9 8
[10] .strtab STRTAB 0000000000000000 0001a8 000010 00 0 0 1
[11] .shstrtab STRTAB 0000000000000000 0001e8 000059 00 0 0 1
static int var =1 After compilation, in the .data section of the relocatable object file
The global variable var is initialized to 0:
int var = 0;
int say() {
return var;
}
root@nemo-VirtualBox:~/workspace/learn# gcc -c test.c
root@nemo-VirtualBox:~/workspace/learn# readelf -s -W test.oSymbol table '.symtab' contains 10 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS test.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
3: 0000000000000000 0 SECTION LOCAL DEFAULT 3
4: 0000000000000000 0 SECTION LOCAL DEFAULT 4
5: 0000000000000000 0 SECTION LOCAL DEFAULT 6
6: 0000000000000000 0 SECTION LOCAL DEFAULT 7
7: 0000000000000000 0 SECTION LOCAL DEFAULT 5
8: 0000000000000000 4 OBJECT GLOBAL DEFAULT 4 var
9: 0000000000000000 12 FUNC GLOBAL DEFAULT 1 say
root@nemo-VirtualBox:~/workspace/learn# readelf -S -W test.o
There are 12 section headers, starting at offset 0x240:Section Headers:
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
[ 0] NULL 0000000000000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 0000000000000000 000040 00000c 00 AX 0 0 1
[ 2] .rela.text RELA 0000000000000000 0001b0 000018 18 I 9 1 8
[ 3] .data PROGBITS 0000000000000000 00004c 000000 00 WA 0 0 1
[ 4] .bss NOBITS 0000000000000000 00004c 000004 00 WA 0 0 4
[ 5] .comment PROGBITS 0000000000000000 00004c 00002c 01 MS 0 0 1
[ 6] .note.GNU-stack PROGBITS 0000000000000000 000078 000000 00 0 0 1
[ 7] .eh_frame PROGBITS 0000000000000000 000078 000038 00 A 0 0 8
[ 8] .rela.eh_frame RELA 0000000000000000 0001c8 000018 18 I 9 7 8
[ 9] .symtab SYMTAB 0000000000000000 0000b0 0000f0 18 10 8 8
[10] .strtab STRTAB 0000000000000000 0001a0 000010 00 0 0 1
[11] .shstrtab STRTAB 0000000000000000 0001e0 000059 00 0 0 1
int var =0 After compilation, in the .bss section of the relocatable object file
Local variables are initialized to 0:
static int var = 0;
int say() {
return var;
}
root@nemo-VirtualBox:~/workspace/learn# gcc -c test.c
root@nemo-VirtualBox:~/workspace/learn# readelf -s -W test.oSymbol table '.symtab' contains 10 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS test.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
3: 0000000000000000 0 SECTION LOCAL DEFAULT 3
4: 0000000000000000 0 SECTION LOCAL DEFAULT 4
5: 0000000000000000 4 OBJECT LOCAL DEFAULT 4 var
6: 0000000000000000 0 SECTION LOCAL DEFAULT 6
7: 0000000000000000 0 SECTION LOCAL DEFAULT 7
8: 0000000000000000 0 SECTION LOCAL DEFAULT 5
9: 0000000000000000 12 FUNC GLOBAL DEFAULT 1 say
root@nemo-VirtualBox:~/workspace/learn# readelf -S -W test.o
There are 12 section headers, starting at offset 0x240:Section Headers:
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
[ 0] NULL 0000000000000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 0000000000000000 000040 00000c 00 AX 0 0 1
[ 2] .rela.text RELA 0000000000000000 0001b0 000018 18 I 9 1 8
[ 3] .data PROGBITS 0000000000000000 00004c 000000 00 WA 0 0 1
[ 4] .bss NOBITS 0000000000000000 00004c 000004 00 WA 0 0 4
[ 5] .comment PROGBITS 0000000000000000 00004c 00002c 01 MS 0 0 1
[ 6] .note.GNU-stack PROGBITS 0000000000000000 000078 000000 00 0 0 1
[ 7] .eh_frame PROGBITS 0000000000000000 000078 000038 00 A 0 0 8
[ 8] .rela.eh_frame RELA 0000000000000000 0001c8 000018 18 I 9 7 8
[ 9] .symtab SYMTAB 0000000000000000 0000b0 0000f0 18 10 9 8
[10] .strtab STRTAB 0000000000000000 0001a0 000010 00 0 0 1
[11] .shstrtab STRTAB 0000000000000000 0001e0 000059 00 0 0 1
static int var =0 After compilation, in the .bss section of the relocatable object file
Uninitialized
Global variable var is not initialized:
int var;
int say() {
return var;
}
root@nemo-VirtualBox:~/workspace/learn# gcc -c test.c
root@nemo-VirtualBox:~/workspace/learn# readelf -s -W test.oSymbol table '.symtab' contains 10 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS test.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
3: 0000000000000000 0 SECTION LOCAL DEFAULT 3
4: 0000000000000000 0 SECTION LOCAL DEFAULT 4
5: 0000000000000000 0 SECTION LOCAL DEFAULT 6
6: 0000000000000000 0 SECTION LOCAL DEFAULT 7
7: 0000000000000000 0 SECTION LOCAL DEFAULT 5
8: 0000000000000004 4 OBJECT GLOBAL DEFAULT COM var
9: 0000000000000000 12 FUNC GLOBAL DEFAULT 1 say
After int var is compiled, it is in the .COMMON section of the relocatable object file.
Local variable not initialized:
static int var;
int say() {
return var;
}
root@nemo-VirtualBox:~/workspace/learn# gcc -c test.c
root@nemo-VirtualBox:~/workspace/learn# readelf -s -W test.oSymbol table '.symtab' contains 10 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS test.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
3: 0000000000000000 0 SECTION LOCAL DEFAULT 3
4: 0000000000000000 0 SECTION LOCAL DEFAULT 4
5: 0000000000000000 4 OBJECT LOCAL DEFAULT 4 var
6: 0000000000000000 0 SECTION LOCAL DEFAULT 6
7: 0000000000000000 0 SECTION LOCAL DEFAULT 7
8: 0000000000000000 0 SECTION LOCAL DEFAULT 5
9: 0000000000000000 12 FUNC GLOBAL DEFAULT 1 say
root@nemo-VirtualBox:~/workspace/learn# readelf -S -W test.o
There are 12 section headers, starting at offset 0x240:Section Headers:
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
[ 0] NULL 0000000000000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 0000000000000000 000040 00000c 00 AX 0 0 1
[ 2] .rela.text RELA 0000000000000000 0001b0 000018 18 I 9 1 8
[ 3] .data PROGBITS 0000000000000000 00004c 000000 00 WA 0 0 1
[ 4] .bss NOBITS 0000000000000000 00004c 000004 00 WA 0 0 4
[ 5] .comment PROGBITS 0000000000000000 00004c 00002c 01 MS 0 0 1
[ 6] .note.GNU-stack PROGBITS 0000000000000000 000078 000000 00 0 0 1
[ 7] .eh_frame PROGBITS 0000000000000000 000078 000038 00 A 0 0 8
[ 8] .rela.eh_frame RELA 0000000000000000 0001c8 000018 18 I 9 7 8
[ 9] .symtab SYMTAB 0000000000000000 0000b0 0000f0 18 10 9 8
[10] .strtab STRTAB 0000000000000000 0001a0 000010 00 0 0 1
[11] .shstrtab STRTAB 0000000000000000 0001e0 000059 00 0 0 1
static int var After compilation, in the .bss section of the relocatable target file
constant
Initialized
The global constant var is initialized:
const int var = 0;
int say() {
return var;
}
root@nemo-VirtualBox:~/workspace/learn# gcc -c test.c
root@nemo-VirtualBox:~/workspace/learn# readelf -s -W test.oSymbol table '.symtab' contains 11 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS test.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
3: 0000000000000000 0 SECTION LOCAL DEFAULT 2
4: 0000000000000000 0 SECTION LOCAL DEFAULT 3
5: 0000000000000000 0 SECTION LOCAL DEFAULT 4
6: 0000000000000000 0 SECTION LOCAL DEFAULT 6
7: 0000000000000000 0 SECTION LOCAL DEFAULT 7
8: 0000000000000000 0 SECTION LOCAL DEFAULT 5
9: 0000000000000000 4 OBJECT GLOBAL DEFAULT 4 var
10: 0000000000000000 11 FUNC GLOBAL DEFAULT 1 say
root@nemo-VirtualBox:~/workspace/learn# readelf -S -W test.o
There are 12 section headers, starting at offset 0x248:Section Headers:
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
[ 0] NULL 0000000000000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 0000000000000000 000040 00000b 00 AX 0 0 1
[ 2] .data PROGBITS 0000000000000000 00004b 000000 00 WA 0 0 1
[ 3] .bss NOBITS 0000000000000000 00004b 000000 00 WA 0 0 1
[ 4] .rodata PROGBITS 0000000000000000 00004c 000004 00 A 0 0 4
[ 5] .comment PROGBITS 0000000000000000 000050 00002c 01 MS 0 0 1
[ 6] .note.GNU-stack PROGBITS 0000000000000000 00007c 000000 00 0 0 1
[ 7] .eh_frame PROGBITS 0000000000000000 000080 000038 00 A 0 0 8
[ 8] .rela.eh_frame RELA 0000000000000000 0001d0 000018 18 I 9 7 8
[ 9] .symtab SYMTAB 0000000000000000 0000b8 000108 18 10 9 8
[10] .strtab STRTAB 0000000000000000 0001c0 000010 00 0 0 1
[11] .shstrtab STRTAB 0000000000000000 0001e8 00005c 00 0 0 1
const int var = 0 After compilation, in the .rodata section of the relocatable object file
The local constant var is initialized:
static const int var = 0;
int say() {
return var;
}
root@nemo-VirtualBox:~/workspace/learn# gcc -c test.c
root@nemo-VirtualBox:~/workspace/learn# readelf -s -W test.oSymbol table '.symtab' contains 11 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS test.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
3: 0000000000000000 0 SECTION LOCAL DEFAULT 2
4: 0000000000000000 0 SECTION LOCAL DEFAULT 3
5: 0000000000000000 0 SECTION LOCAL DEFAULT 4
6: 0000000000000000 4 OBJECT LOCAL DEFAULT 4 var
7: 0000000000000000 0 SECTION LOCAL DEFAULT 6
8: 0000000000000000 0 SECTION LOCAL DEFAULT 7
9: 0000000000000000 0 SECTION LOCAL DEFAULT 5
10: 0000000000000000 11 FUNC GLOBAL DEFAULT 1 say
root@nemo-VirtualBox:~/workspace/learn# readelf -S -W test.o
There are 12 section headers, starting at offset 0x248:Section Headers:
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
[ 0] NULL 0000000000000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 0000000000000000 000040 00000b 00 AX 0 0 1
[ 2] .data PROGBITS 0000000000000000 00004b 000000 00 WA 0 0 1
[ 3] .bss NOBITS 0000000000000000 00004b 000000 00 WA 0 0 1
[ 4] .rodata PROGBITS 0000000000000000 00004c 000004 00 A 0 0 4
[ 5] .comment PROGBITS 0000000000000000 000050 00002c 01 MS 0 0 1
[ 6] .note.GNU-stack PROGBITS 0000000000000000 00007c 000000 00 0 0 1
[ 7] .eh_frame PROGBITS 0000000000000000 000080 000038 00 A 0 0 8
[ 8] .rela.eh_frame RELA 0000000000000000 0001d0 000018 18 I 9 7 8
[ 9] .symtab SYMTAB 0000000000000000 0000b8 000108 18 10 10 8
[10] .strtab STRTAB 0000000000000000 0001c0 000010 00 0 0 1
[11] .shstrtab STRTAB 0000000000000000 0001e8 00005c 00 0 0 1
static const int var = 0 After compilation, in the .rodata section of the relocatable object file
Uninitialized
Global constant var is not initialized:
const int var;
int say() {
return var;
}
root@nemo-VirtualBox:~/workspace/learn# gcc -c test.c
root@nemo-VirtualBox:~/workspace/learn# readelf -s -W test.oSymbol table '.symtab' contains 10 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS test.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
3: 0000000000000000 0 SECTION LOCAL DEFAULT 3
4: 0000000000000000 0 SECTION LOCAL DEFAULT 4
5: 0000000000000000 0 SECTION LOCAL DEFAULT 6
6: 0000000000000000 0 SECTION LOCAL DEFAULT 7
7: 0000000000000000 0 SECTION LOCAL DEFAULT 5
8: 0000000000000004 4 OBJECT GLOBAL DEFAULT COM var
9: 0000000000000000 12 FUNC GLOBAL DEFAULT 1 say
const int var After compilation, in the .COMMON section of the relocatable object file
Local constant var is not initialized:
static const int var;
int say() {
return var;
}
root@nemo-VirtualBox:~/workspace/learn# gcc -c test.c
root@nemo-VirtualBox:~/workspace/learn# readelf -s -W test.oSymbol table '.symtab' contains 10 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS test.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
3: 0000000000000000 0 SECTION LOCAL DEFAULT 2
4: 0000000000000000 0 SECTION LOCAL DEFAULT 3
5: 0000000000000000 4 OBJECT LOCAL DEFAULT 3 var
6: 0000000000000000 0 SECTION LOCAL DEFAULT 5
7: 0000000000000000 0 SECTION LOCAL DEFAULT 6
8: 0000000000000000 0 SECTION LOCAL DEFAULT 4
9: 0000000000000000 11 FUNC GLOBAL DEFAULT 1 say
root@nemo-VirtualBox:~/workspace/learn# readelf -S -W test.o
There are 11 section headers, starting at offset 0x220:Section Headers:
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
[ 0] NULL 0000000000000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 0000000000000000 000040 00000b 00 AX 0 0 1
[ 2] .data PROGBITS 0000000000000000 00004b 000000 00 WA 0 0 1
[ 3] .bss NOBITS 0000000000000000 00004c 000004 00 WA 0 0 4
[ 4] .comment PROGBITS 0000000000000000 00004c 00002c 01 MS 0 0 1
[ 5] .note.GNU-stack PROGBITS 0000000000000000 000078 000000 00 0 0 1
[ 6] .eh_frame PROGBITS 0000000000000000 000078 000038 00 A 0 0 8
[ 7] .rela.eh_frame RELA 0000000000000000 0001b0 000018 18 I 8 6 8
[ 8] .symtab SYMTAB 0000000000000000 0000b0 0000f0 18 9 9 8
[ 9] .strtab STRTAB 0000000000000000 0001a0 000010 00 0 0 1
[10] .shstrtab STRTAB 0000000000000000 0001c8 000054 00 0 0 1
static const int var After compilation, in the .bss section of the relocatable object file
Summarize:
index | definition | Attributes | scope | Assignment | location |
1 | int a = 1 | variable | overall situation | any (except default empty value) | .data |
2 | static int a = 1 | variable | local | any (except default empty value) | .data |
3 | int a = 0 | variable | overall situation | Default empty value | .bss |
4 | static int a = 0 | variable | local | Default empty value | .bss |
5 | int a | variable | overall situation | Uninitialized | .COMMON |
6 | static int a | variable | local | Uninitialized | .bss |
7 | const int a = 0 | constant | overall situation | any | .rodata |
8 | static const int a = 0 | constant | local | any | .rodata |
9 | const int a | constant | overall situation | Uninitialized | .COMMON |
10 | static const int a | constant | local | Uninitialized | .bss |
- When a variable is initialized to a non-default null value, the compiler places it in the .data section (1, 2)
- When a variable is initialized to the default null value, since .bss does not occupy space, the compiler optimizes and places it in the .bss section (3, 4)
- Uninitialized global variables, because they are weak symbols, cannot determine the reference address at compile time, so they are placed in the .COMMON section, and the reference address is determined by the connector (5)
- Uninitialized local variables. Since the scope is in this module, the compiler can determine the address referencing this variable. At the same time, because it is not initialized, it is placed in the .bss section (6)
- After the constant is initialized, the compiler places it in .rodata (7,8)
- Uninitialized global constants, because they are weak symbols, cannot determine the reference address at compile time, so they are placed in the .COMMON section, and the reference address is determined by the connector (9)
- Uninitialized local constant. Since the scope is in this module, the compiler can determine the address referencing this constant. At the same time, because it is not initialized, it is placed in the .bss section (10)
question:
Since uninitialized local constants are placed in the .bss section, and the data in the .bss section can be modified, you can modify this value through a pointer, and then obtain the modified value through the pointer!
Example:
#include <stdio.h>
static const int var;
void set_var(int);
int get_var();
int main() {
set_var(10);
printf("%d\n", get_var());
}
void set_var(int v) {
int *p = &var;
*p = v;
}
int get_var() {
int *p = &var;
return *p;
}
root@nemo-VirtualBox:~/workspace/learn# gcc test.c
test.c: In function ‘set_var’:
test.c:19:14: warning: initialization discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
int *p = &var;
^
test.c: In function ‘get_var’:
test.c:24:14: warning: initialization discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
int *p = &var;
^
root@nemo-VirtualBox:~/workspace/learn# ./a.out
10
Because var is on .bss, we successfully modified the value of the local constant.
We make a small modification and assign an initial value of 0 to the local constant (it seems to be no different from the above), but. . .
#include <stdio.h>
static const int var = 0;
void set_var(int);
int get_var();
int main() {
set_var(10);
printf("%d\n", get_var());
}
void set_var(int v) {
int *p = &var;
*p = v;
}
int get_var() {
int *p = &var;
return *p;
}
root@nemo-VirtualBox:~/workspace/learn# gcc test.c
test.c: In function ‘set_var’:
test.c:19:14: warning: initialization discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
int *p = &var;
^
test.c: In function ‘get_var’:
test.c:24:14: warning: initialization discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
int *p = &var;
^
root@nemo-VirtualBox:~/workspace/learn# ./a.out
Segmentation fault (core dumped)
Because we assigned the local constant an initial value of 0, it was placed in the .rodata section by the compiler, and the data in the .rodata section is read-only. When writing, the operating system generates a segmentation fault. In order to avoid some strange errors, we recommend that constants must be assigned a value (even if the value is 0)