關於weakref的用法

在《程序員的自我修養—鏈接、裝載、庫》這本書的3.5.5節,講到了一個知識點:weakref,弱引用。

書中在第93頁舉出的例子發現編譯不通過,報錯。

__attribute__((weakref)) void foo();

int main()
{
	foo();
}


據網絡文檔介紹,有四種weakref的用法,我自己試驗下來只有三種,還有一種一直報錯,沒懂怎麼用。

int y()
{
	return 0;
}

/*
可以這麼聲明但是不能調用,會報錯
*/
int x1() __attribute__ ((weakref));

/*
可以調用
函數必須是static
int x() __attribute__ ((weakref ("y")));這樣會報錯
*/
static int x2() __attribute__ ((weakref ("y")));

/*
可以調用
需要定義y函數,可以去除static屬性
*/
static int x3() __attribute__ ((alias ("y")));

int main()
{
	x2();
	x3();
	return 0;
}
書中舉出的例子,寫法沒錯,但錯就錯在它在函數中調用了這個弱引用,如果不調用就不會報錯了。關於這個調用,還有一個,網上很多解決方法是將weakref改成weakref,也就是下面這樣

__attribute__((weak)) void foo();
這種方法也可以在有函數中調用該函數的情況下,編譯通過。文檔也有提到,當weakref沒有參數時和weak相同,但個人不推薦這種寫法。

此外,alias和weakref("argument")這兩種寫法都是類似於找個備胎,如果這個函數沒定義,就用備用的。

weakref1.c

#include <stdio.h>
void fun2()
{
	printf("this is fun2\n");
}
weakref.c

static __attribute__((weakref("fun2")))void fun1();
int main()
{
	fun1();
	return 0;
}
此時實際輸出的是函數fun2的內容。

如果fun1已經有了定義,則輸出fun1的內容。前提是fun1的聲明/定義要在fun2之前。

另外有一種報錯的寫法是下面這樣子的:

static int x() __attribute__ ((weak, weakref, alias ("y")));
這個寫法,不管是不是把static屬性去掉,都會報錯。


這個用法還沒搞明白。


下面是網上找的關於weakref用法的一些說明。

weakref
weakref ("target")
The weakref attribute marks a declaration as a weak reference. Without arguments, it should be accompanied by an alias attribute naming the target symbol. Optionally, the target may be given as an argument to weakref itself. In either case, weakref implicitly marks the declaration as weak. Without a target, given as an argument to weakref or to alias, weakref is equivalent to weak.

static int x() __attribute__ ((weakref ("y")));
/* is equivalent to... */
static int x() __attribute__ ((weak, weakref, alias ("y")));
/* and to... */
static int x() __attribute__ ((weakref));
static int x() __attribute__ ((alias ("y")));
A weak reference is an alias that does not by itself require a definition to be given for the target symbol. If the target symbol is only referenced through weak references, then it becomes a weak undefined symbol. If it is directly referenced, however, then such strong references prevail, and a definition is required for the symbol, not necessarily in the same translation unit.

The effect is equivalent to moving all references to the alias to a separate translation unit, renaming the alias to the aliased symbol, declaring it as weak, compiling the two separate translation units and performing a reloadable link on them.

At present, a declaration to which weakref is attached can only be static.
這是網頁源地址點擊打開鏈接




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章