// a.c
int a = 3;
// b.c
#include <stdio.h>
int a;
int main()
{
printf("a=%d\n", a);
return 0;
}
gcc a.c b.c -c
[hubingbing@pekphis193995 test_linkage2]$ readelf -s a.o
Symbol table '.symtab' contains 9 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS a.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 NOTYPE LOCAL DEFAULT 2 $d
6: 0000000000000000 0 SECTION LOCAL DEFAULT 5
7: 0000000000000000 0 SECTION LOCAL DEFAULT 4
8: 0000000000000000 4 OBJECT GLOBAL DEFAULT 2 a
[hubingbing@pekphis193995 test_linkage2]$ readelf -s b.o
Symbol table '.symtab' contains 15 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS b.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 5
6: 0000000000000000 0 NOTYPE LOCAL DEFAULT 5 $d
7: 0000000000000000 0 NOTYPE LOCAL DEFAULT 1 $x
8: 0000000000000000 0 SECTION LOCAL DEFAULT 7
9: 0000000000000014 0 NOTYPE LOCAL DEFAULT 8 $d
10: 0000000000000000 0 SECTION LOCAL DEFAULT 8
11: 0000000000000000 0 SECTION LOCAL DEFAULT 6
12: 0000000000000004 4 OBJECT GLOBAL DEFAULT COM a
13: 0000000000000000 44 FUNC GLOBAL DEFAULT 1 main
14: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND printf
[hubingbing@pekphis193995 test_linkage2]$ g++ a.c b.c -c
[hubingbing@pekphis193995 test_linkage2]$ readelf -s a.o
Symbol table '.symtab' contains 9 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS a.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 NOTYPE LOCAL DEFAULT 2 $d
6: 0000000000000000 0 SECTION LOCAL DEFAULT 5
7: 0000000000000000 0 SECTION LOCAL DEFAULT 4
8: 0000000000000000 4 OBJECT GLOBAL DEFAULT 2 a
[hubingbing@pekphis193995 test_linkage2]$ readelf -s b.o
Symbol table '.symtab' contains 16 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS b.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 NOTYPE LOCAL DEFAULT 4 $d
6: 0000000000000000 0 SECTION LOCAL DEFAULT 5
7: 0000000000000000 0 NOTYPE LOCAL DEFAULT 5 $d
8: 0000000000000000 0 NOTYPE LOCAL DEFAULT 1 $x
9: 0000000000000000 0 SECTION LOCAL DEFAULT 7
10: 0000000000000014 0 NOTYPE LOCAL DEFAULT 8 $d
11: 0000000000000000 0 SECTION LOCAL DEFAULT 8
12: 0000000000000000 0 SECTION LOCAL DEFAULT 6
13: 0000000000000000 4 OBJECT GLOBAL DEFAULT 4 a
14: 0000000000000000 44 FUNC GLOBAL DEFAULT 1 main
15: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND printf
[hubingbing@pekphis193995 test_linkage2]$
特别注意,g++编译出来的b.o,a是在第4段,视作定义而非声明。而gcc编译出来的b.o,a在common段,视为声明,不分配空间。
所以上述代码gcc能编过并链接成功,而g++链接会报错。
// a.c
int x;
void func() {
x = 20;
}
// b.c
#include "stdio.h"
short x = 10;
short y = 10;
extern void func();
int main()
{
printf("before call func: x = %d, y = %d\n", x, y);
func();
printf("after call func: x = %d, y = %d\n", x, y);
printf("sizeof(x)=%lu, sizeof(y)=%lu\n", sizeof(x), sizeof(y));
return 0;
}
[hubingbing@pekphis193995 test_linkage]$ gcc a.c b.c
/usr/bin/ld: warning: alignment 2 of symbol `x' in /tmp/ccoKSrLO.o is smaller than 4 in /tmp/cc8Qpcod.o
/usr/bin/ld: warning: size of symbol `x' changed from 4 in /tmp/cc8Qpcod.o to 2 in /tmp/ccoKSrLO.o
[hubingbing@pekphis193995 test_linkage]$ ./a.out
before call func: x = 10, y = 10
after call func: x = 20, y = 0
sizeof(x)=2, sizeof(y)=2