c 和 c++ 對 const 有不同的解釋
a.c
1 #include <stdio.h>
2
3 extern const int abc;
4
5 int main(int argc, char *argv[])
6 {
7 printf("hello c++, abc: %d\n", abc);
8 return 0;
9 }
b.c
1 const int abc=1;
2
3 int fun1()
4 {
5 return abc + 5;
6 }
gcc -save-temps a.c b.c -o a
list 1 b.o.elf
1 ELF Header:
2 Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
3 Class: ELF64
4 Data: 2's complement, little endian
5 Version: 1 (current)
6 OS/ABI: UNIX - System V
7 ABI Version: 0
8 Type: REL (Relocatable file)
9 Machine: Advanced Micro Devices X86-64
10 Version: 0x1
11 Entry point address: 0x0
12 Start of program headers: 0 (bytes into file)
13 Start of section headers: 576 (bytes into file)
14 Flags: 0x0
15 Size of this header: 64 (bytes)
16 Size of program headers: 0 (bytes)
17 Number of program headers: 0
18 Size of section headers: 64 (bytes)
19 Number of section headers: 12
20 Section header string table index: 11
21
22 Section Headers:
23 [Nr] Name Type Address Offset
24 Size EntSize Flags Link Info Align
25 [ 0] NULL 0000000000000000 00000000
26 0000000000000000 0000000000000000 0 0 0
27 [ 1] .text PROGBITS 0000000000000000 00000040
28 000000000000000e 0000000000000000 AX 0 0 1
29 [ 2] .data PROGBITS 0000000000000000 0000004e
30 0000000000000000 0000000000000000 WA 0 0 1
31 [ 3] .bss NOBITS 0000000000000000 0000004e
32 0000000000000000 0000000000000000 WA 0 0 1
33 [ 4] .rodata PROGBITS 0000000000000000 00000050
34 0000000000000004 0000000000000000 A 0 0 4
35 [ 5] .comment PROGBITS 0000000000000000 00000054
36 000000000000001d 0000000000000001 MS 0 0 1
37 [ 6] .note.GNU-stack PROGBITS 0000000000000000 00000071
38 0000000000000000 0000000000000000 0 0 1
39 [ 7] .eh_frame PROGBITS 0000000000000000 00000078
40 0000000000000038 0000000000000000 A 0 0 8
41 [ 8] .rela.eh_frame RELA 0000000000000000 000001c8
42 0000000000000018 0000000000000018 I 9 7 8
43 [ 9] .symtab SYMTAB 0000000000000000 000000b0
44 0000000000000108 0000000000000018 10 9 8
45 [10] .strtab STRTAB 0000000000000000 000001b8
46 000000000000000e 0000000000000000 0 0 1
47 [11] .shstrtab STRTAB 0000000000000000 000001e0
48 000000000000005c 0000000000000000 0 0 1
49 Key to Flags:
50 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
51 L (link order), O (extra OS processing required), G (group), T (TLS),
52 C (compressed), x (unknown), o (OS specific), E (exclude),
53 l (large), p (processor specific)
54
55 There are no section groups in this file.
56
57 There are no program headers in this file.
58
59 There is no dynamic section in this file.
60
61 Relocation section '.rela.eh_frame' at offset 0x1c8 contains 1 entry:
62 Offset Info Type Sym. Value Sym. Name + Addend
63 000000000020 000200000002 R_X86_64_PC32 0000000000000000 .text + 0
64
65 The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.
66
67 Symbol table '.symtab' contains 11 entries:
68 Num: Value Size Type Bind Vis Ndx Name
69 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
70 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS b.c
71 2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
72 3: 0000000000000000 0 SECTION LOCAL DEFAULT 2
73 4: 0000000000000000 0 SECTION LOCAL DEFAULT 3
74 5: 0000000000000000 0 SECTION LOCAL DEFAULT 4
75 6: 0000000000000000 0 SECTION LOCAL DEFAULT 6
76 7: 0000000000000000 0 SECTION LOCAL DEFAULT 7
77 8: 0000000000000000 0 SECTION LOCAL DEFAULT 5
78 9: 0000000000000000 4 OBJECT GLOBAL DEFAULT 4 abc
79 10: 0000000000000000 14 FUNC GLOBAL DEFAULT 1 fun1
80
81 No version information found in this file.
這個問題要從 link time 才能發現, 並不是編譯時期的問題, list 1 L78 顯示 bind 欄位是 global, 所以其他編譯單元看得到這個 const abc 變數。
a.cpp
1 #include <stdio.h>
2
3 extern const int abc;
4
5 int main(int argc, char *argv[])
6 {
7 printf("hello c++, abc: %d\n", abc);
8 return 0;
9 }
b.cpp
1 const int abc=1;
2
3 int fun1()
4 {
5 return abc + 5;
6 }
descent@debian64:tmp$ g++ -save-temps a.cpp b.cpp -o a
/usr/bin/ld: a.o: in function `main':
a.cpp:(.text+0x11): undefined reference to `abc'
collect2: error: ld returned 1 exit status
list 2 b.cpp.o.elf
1 ELF Header:
2 Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
3 Class: ELF64
4 Data: 2's complement, little endian
5 Version: 1 (current)
6 OS/ABI: UNIX - System V
7 ABI Version: 0
8 Type: REL (Relocatable file)
9 Machine: Advanced Micro Devices X86-64
10 Version: 0x1
11 Entry point address: 0x0
12 Start of program headers: 0 (bytes into file)
13 Start of section headers: 576 (bytes into file)
14 Flags: 0x0
15 Size of this header: 64 (bytes)
16 Size of program headers: 0 (bytes)
17 Number of program headers: 0
18 Size of section headers: 64 (bytes)
19 Number of section headers: 12
20 Section header string table index: 11
21
22 Section Headers:
23 [Nr] Name Type Address Offset
24 Size EntSize Flags Link Info Align
25 [ 0] NULL 0000000000000000 00000000
26 0000000000000000 0000000000000000 0 0 0
27 [ 1] .text PROGBITS 0000000000000000 00000040
28 000000000000000b 0000000000000000 AX 0 0 1
29 [ 2] .data PROGBITS 0000000000000000 0000004b
30 0000000000000000 0000000000000000 WA 0 0 1
31 [ 3] .bss NOBITS 0000000000000000 0000004b
32 0000000000000000 0000000000000000 WA 0 0 1
33 [ 4] .rodata PROGBITS 0000000000000000 0000004c
34 0000000000000004 0000000000000000 A 0 0 4
35 [ 5] .comment PROGBITS 0000000000000000 00000050
36 000000000000001d 0000000000000001 MS 0 0 1
37 [ 6] .note.GNU-stack PROGBITS 0000000000000000 0000006d
38 0000000000000000 0000000000000000 0 0 1
39 [ 7] .eh_frame PROGBITS 0000000000000000 00000070
40 0000000000000038 0000000000000000 A 0 0 8
41 [ 8] .rela.eh_frame RELA 0000000000000000 000001c8
42 0000000000000018 0000000000000018 I 9 7 8
43 [ 9] .symtab SYMTAB 0000000000000000 000000a8
44 0000000000000108 0000000000000018 10 10 8
45 [10] .strtab STRTAB 0000000000000000 000001b0
46 0000000000000018 0000000000000000 0 0 1
47 [11] .shstrtab STRTAB 0000000000000000 000001e0
48 000000000000005c 0000000000000000 0 0 1
49 Key to Flags:
50 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
51 L (link order), O (extra OS processing required), G (group), T (TLS),
52 C (compressed), x (unknown), o (OS specific), E (exclude),
53 l (large), p (processor specific)
54
55 There are no section groups in this file.
56
57 There are no program headers in this file.
58
59 There is no dynamic section in this file.
60
61 Relocation section '.rela.eh_frame' at offset 0x1c8 contains 1 entry:
62 Offset Info Type Sym. Value Sym. Name + Addend
63 000000000020 000200000002 R_X86_64_PC32 0000000000000000 .text + 0
64
65 The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.
66
67 Symbol table '.symtab' contains 11 entries:
68 Num: Value Size Type Bind Vis Ndx Name
69 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
70 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS b.cpp
71 2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
72 3: 0000000000000000 0 SECTION LOCAL DEFAULT 2
73 4: 0000000000000000 0 SECTION LOCAL DEFAULT 3
74 5: 0000000000000000 0 SECTION LOCAL DEFAULT 4
75 6: 0000000000000000 4 OBJECT LOCAL DEFAULT 4 _ZL3abc
76 7: 0000000000000000 0 SECTION LOCAL DEFAULT 6
77 8: 0000000000000000 0 SECTION LOCAL DEFAULT 7
78 9: 0000000000000000 0 SECTION LOCAL DEFAULT 5
79 10: 0000000000000000 11 FUNC GLOBAL DEFAULT 1 _Z4fun1v
80
81 No version information found in this file.
list 2 L75 bind 顯示是 local, 所以其他編譯單元看不到。
c++ 的 const 會有類似 static 的效果, 這個 abc 變數只能在 b.cpp 檔案使用, a.cpp 看不到這個變數。
不過我在 c++ primer 3rd 找不到這個說明, 不知道哪本書有寫?
沒有留言:
張貼留言
使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。
我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。