Compiler會把已經初始化的Global varible當作Strong Symbol
未初始化的Global varible為Weak Symbol
我們可以使用GCC提供的 "__attribute__((weak))"
來定義任意一個Strong Symbol為Weak Symbol
以下是一個例子:
extern int ext; int weak; int strong = 1; __attribute__((weak)) weak2 = 2; int main(){ return 0; }
在這個例子中weak和weak2都是Weak Symbol
strong和main是Strong Symbol
ext不是Strong也不是Weak,因為他是一個外部變數
Compiler會按照下列規則處理Strong以及Weak Symbol
Rule1: Strong Symbol不能在不同的Obj檔被多次定義
這就是我們常常看到的重複定義錯誤
Rule2: 如果一個Symbol在某個檔案是Strong,在其他檔案都是Weak
Compiler會選擇Strong Symbol
Rule3: 如果一個Symbol在每個檔案都是Weak,會選擇最大的Type
比如說一個同樣名稱的int和double global varible
Compiler在Link的時候會選擇double
外部符號的Reference也有分兩種
Strong Reference: 在Link時找不到符號定義會回報錯誤
Weak Reference: 在Link時找不到符號定義不會回報錯誤,通常會預設為0
下面是GCC把foo()宣告成weak reference的擴充keyword
__attribute__((weakref)) void foo(); int main() { foo(); }上面這段code可以編譯成執行檔且不會產生錯誤
但是我們執行程式的話,因為沒有定義foo(),foo的位置為0
因此會發生不合法的位置存取錯誤
Weak Symbol和 Weak Reference對函式庫的設計非常有用
函式庫可以定義一些Weak Symbol的函式
使用者可以自己定義一些Strong Symbol達到擴充功能
因為Strong Symbol會蓋掉Weak Symobl
我們也可以透過Weak Reference使用一些擴充功能
以後就算我們把擴充功能去掉,程式還是可以正常Link
沒有留言:
張貼留言