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