Monday, September 15, 2008

weak symbol

nm的manual里的说明:
When a  weak  defined symbol is linked with a normal defined symbol, the normal defined symbol is used with no error.  When a weak undefined symbol is linked and the symbol is not defined,  the  value of  the  symbol is determined in a system-specific manner without error.  On some systems, upper-case indicates that a default value has been specified.

网上其它有关的说明:
weak symbols can very well exist many or zero times. This will not cause any problem. If no symbol is found, a null one is provided. In case many symbols are found, the first one is taken and used by everybody.
(http://proj-gaudi.web.cern.ch/proj-gaudi/tricks/dynamic_cast.php)

测试程序:
说明:
  1. null为空,固打印了"not found null".
  2. strong函数的定义一处为weak,一处为strong,则链接器选用后者
  3. weak函数的定义两处都为weak,则链接器选用链接器所看到的第一个weak. (固更改链接命令o文件的位置即可得到不同的效果)
  4. 该测试只针对静态链接,对于动态链接效果怎么还末知
--------------------------------------------------
weak.c
--------------------------------------------------
extern void null() __attribute__((weak));
extern void strong() __attribute__((weak));
extern void weak() __attribute__((weak));

void strong()
{
    printf("false strong\n");
}

void weak()
{
    printf("first weak\n");
}

main()
{
    if(!null)
        printf("not found null \n");
    
    strong();
    weak();
}

--------------------------------------------------
strong.c
--------------------------------------------------
void strong()
{
    printf("true strong\n");
}

extern void weak() __attribute__((weak));
void weak()
{
    printf("second weak\n");
}

--------------------------------------------------
Makefile
--------------------------------------------------
.PHONY:clean

CFLAGS := -g -O0

%.o:%.c
    gcc $(CFLAGS) -o $@ -c $^
weak:  weak.o strong.o
#weak:   strong.o weak.o
    gcc $^ -o $@

weak.o: weak.c

strong.o: strong.c

clean:
    rm *.o

--------------------------------------------------
output:
--------------------------------------------------
[dybbuk@localhost tmp]$ ./weak
not found null
true strong
first weak
[dybbuk@localhost tmp]$ nm weak.o
00000028 T main
         w null
         U puts
00000000 W strong
00000014 W weak
[dybbuk@localhost tmp]$ nm strong.o
         U puts
00000000 T strong
00000014 W weak