强符号和弱符号

           在C语言中,函数和初始化的全局变量(包括显示初始化为0)是强符号,未初始化的全局变量是强符号。关于多个强弱符号定义类型不一致的主要有下面三种情况:

1.两个或两个以上强符号类型不一致

2.有一个强符号,其他都是弱符号

3.两个或两个以上弱符号类型不一致

对于情况一,编译会报符号重定义错误。


对于情况二,链接最终会选择强符号。示例代码如下:

[mapan@localhost 2]$ cat a.c 
#include <stdio.h>

int shared;

int main()
{
   int a = 100;
   swap(&a,&shared);

   return 0;
}
[mapan@localhost 2]$ cat b.c 
#include <stdio.h>

int shared = 2;

void swap(int *a,int *b)
{
   *a *= *b;
   printf("a = %d\n",*a);
}
[mapan@localhost 2]$ gcc a.c b.c 
[mapan@localhost 2]$ ./a.out 
a = 200
[mapan@localhost 2]$ 

编译没报错,并且打印出正确结果。链接取的强符号(已初始化的全局变量)。这是强弱符号类型一样的情况,强弱符号类型不一下的情况如下:

[mapan@localhost 2]$ cat a.c 
#include <stdio.h>

long shared = 1;

int main()
{
   printf("%d\n",shared);

   return 0;
}
[mapan@localhost 2]$ cat b.c 
#include <stdio.h>

int shared ;

[mapan@localhost 2]$ gcc a.c b.c 
[mapan@localhost 2]$ ./a.out 
1
[mapan@localhost 2]$ 

编译正常。这是强类符号的大小大于弱类型符号大小。再看:

[mapan@localhost 2]$ cat a.c 
#include <stdio.h>

long shared ;

int main()
{
   printf("%d\n",shared);

   return 0;
}
[mapan@localhost 2]$ cat b.c 
#include <stdio.h>

int shared = 1;

[mapan@localhost 2]$ gcc a.c b.c 
/usr/bin/ld: Warning: alignment 4 of symbol `shared' in /tmp/ccNlFnUp.o is smaller than 8 in /tmp/ccp5HfsC.o
/usr/bin/ld: Warning: size of symbol `shared' changed from 8 in /tmp/ccp5HfsC.o to 4 in /tmp/ccNlFnUp.o
[mapan@localhost 2]$ ./a.out 
1
[mapan@localhost 2]$ 
编译产生警告信息, 这是因为2个目标文件的COMMON块不一致(未初始化的全局变量存放在COMMON块)。当不同的目标文件需要COMMON块空间大小不一致时,以最大的那块为准。


对于情况三,编译正常,没啥好说的了。








猜你喜欢

转载自blog.csdn.net/ma2595162349/article/details/78989962