weak:表示当前符号是个弱类型符号(weak symbol),而非全局符号。看个示例:
1,首先,准备一个库文件(以静态库为例,后文将提到为什么不以动态库为例):
[root@localhost weak_test1]# cat /etc/issue
CentOS release 6.2 (Final)
Kernel \r on an \m
[root@localhost weak_test1]# uname -a
Linux localhost.localdomain 2.6.32-220.el6.i686 #1 SMP Tue Dec 6 16:15:40 GMT 2011 i686 i686 i386 GNU/Linux
[root@localhost weak_test1]# vi mylib.c
[root@localhost weak_test1]# cat !$
cat mylib.c
#include <stdio.h>
void
foo()
{
printf
(
"lib test\n"
);
}
void
foo() __attribute__ ((weak));
[root@localhost weak_test1]# <span
class
=
"wp_keywordlink_affiliate"
><a href=
"http://lenky.info/tag/gcc/"
title=
"查看 gcc 中的全部文章"
>gcc</a></span> -c mylib.c
[root@localhost weak_test1]# ar crv libmylib.a mylib.o
a - mylib.o
可以看到libmylib.a库里定义了一个函数foo(),并且是weak弱类型。
2,编写一个应用程序(由两个源文件myapp.c与myfoo.c构成):
[root@localhost weak_test1]# vi myapp.c
[root@localhost weak_test1]# cat !$
cat myapp.c
#include <stdio.h>
int
main()
{
foo();
return
0;
}
[root@localhost weak_test1]# vi myfoo.c
[root@localhost weak_test1]# cat !$
cat myfoo.c
#include <stdio.h>
void
foo()
{
printf
(
"app test\n"
);
}
源文件myfoo.c调用的foo()函数可以来自libmylib.a库,也可以来自应用程序的另外一个源文件,连接并执行:
[root@localhost weak_test1]# gcc myapp.c myfoo.c libmylib.a -o myapp_weak
[root@localhost weak_test1]# ./myapp_weak
app test
打印显示的是app test,即调用的是应用程序自身的函数foo()。
3,如果应用程序本身不提供函数foo(),那么情况是怎样:
[root@localhost weak_test1]# gcc myapp.c libmylib.a -o myapp
[root@localhost weak_test1]# ./myapp
lib test
打印显示的是lib test,即调用了libmylib.a库里的weak弱类型函数foo()。
4,试试去掉库里的weak修饰:
[root@localhost weak_test1]# vi mylib.c
[root@localhost weak_test1]# cat mylib.c
#include <stdio.h>
void
foo()
{
printf
(
"lib test\n"
);
}
//void foo() __attribute__ ((weak));
[root@localhost weak_test1]# gcc -c mylib.c;ar crv libmylib.a mylib.o
r - mylib.o
[root@localhost weak_test1]# gcc myapp.c myfoo.c libmylib.a -o myapp
[root@localhost weak_test1]# ./myapp
app test
去掉weak修饰后也没问题?那weak属性到底有啥用?试试把libmylib.a放前面:
[root@localhost weak_test1]# gcc myapp.c libmylib.a myfoo.c -o myapp
/tmp/ccIjvazY.o: In function `foo':
myfoo.c:(.text+0x0): multiple definition of `foo'
libmylib.a(mylib.o):mylib.c:(.text+0x0): first defined here
collect2: ld returned 1
exit
status
[root@localhost weak_test1]# gcc libmylib.a myapp.c myfoo.c -o myapp
[root@localhost weak_test1]# gcc libmylib.a myfoo.c myapp.c -o myapp
[root@localhost weak_test1]# gcc myfoo.c libmylib.a myapp.c -o myapp
[root@localhost weak_test1]# gcc myfoo.c myapp.c libmylib.a -o myapp
对比一下,加上weak修饰:
[root@localhost weak_test1]# vi mylib.c
[root@localhost weak_test1]# cat mylib.c
#include <stdio.h>
void
foo()
{
printf
(
"lib test\n"
);
}
void
foo() __attribute__ ((weak));
[root@localhost weak_test1]# gcc -c mylib.c;ar crv libmylib.a mylib.o
r - mylib.o
[root@localhost weak_test1]# gcc myapp.c libmylib.a myfoo.c -o myapp
[root@localhost weak_test1]# gcc libmylib.a myapp.c myfoo.c -o myapp
[root@localhost weak_test1]# gcc libmylib.a myfoo.c myapp.c -o myapp
[root@localhost weak_test1]# gcc myfoo.c libmylib.a myapp.c -o myapp
[root@localhost weak_test1]# gcc myfoo.c myapp.c libmylib.a -o myapp
[root@localhost weak_test1]# ./myapp
app test
去掉weak修饰后,只有一个杯具的报错了,难道是和库文件排放位置相关?不用库函数,直接用源代码试试:
[root@localhost weak_test1]# vi mylib.c
[root@localhost weak_test1]# cat mylib.c
#include <stdio.h>
void
foo()
{
printf
(
"lib test\n"
);
}
//void foo() __attribute__ ((weak));
[root@localhost weak_test1]# gcc myapp.c myfoo.c mylib.c -o myapp
/tmp/ccbKVCYU.o: In function `foo':
mylib.c:(.text+0x0): multiple definition of `foo'
/tmp/cc3DKEyS.o:myfoo.c:(.text+0x0): first defined here
collect2: ld returned 1
exit
status
[root@localhost weak_test1]# gcc myapp.c mylib.c myfoo.c -o myapp
/tmp/ccosX9JJ.o: In function `foo':
myfoo.c:(.text+0x0): multiple definition of `foo'
/tmp/ccyyg6us.o:mylib.c:(.text+0x0): first defined here
collect2: ld returned 1
exit
status
报错(必然的),加上:
[root@localhost weak_test1]# vi mylib.c
[root@localhost weak_test1]# cat mylib.c
#include <stdio.h>
void
foo()
{
printf
(
"lib test\n"
);
}
void
foo() __attribute__ ((weak));
[root@localhost weak_test1]# gcc myapp.c myfoo.c mylib.c -o myapp
[root@localhost weak_test1]# gcc myapp.c mylib.c myfoo.c -o myapp