4.1.19. __weak

此关键字指示编译器弱导出符号。

可以将 __weak 关键字应用于函数和变量声明以及函数定义。

用法

函数和变量声明

对于声明,此存储类指定一个 extern 对象声明,即使不存在,也不会导致链接器将未解析的引用作为错误处理。

例如:


__weak void f(void);

...

f(); // call f weakly

如果从编译为跳转或跳转链接指令的代码中对缺少的弱函数进行引用,则会:

  • 将该引用解析为下一条指令的跳转。 这实际上将跳转变为 NOP

  • 将该跳转替换为 NOP 指令。

函数定义

使用 __weak 定义的函数将弱导出其符号。 除非将相同名称的非弱定义函数链接到相同映像上,否则弱定义函数的行为与正常定义的函数类似。 如果非弱定义函数和弱定义函数位于相同映像中,则会将对弱定义函数的所有调用解析为对非弱函数的调用。 如果有多个可用的弱定义,链接器将选择其中的一个弱定义供所有调用使用。

如果使用 __weak 声明函数,但随后没有使用 __weak 对其进行定义,则此函数与非弱函数的行为相同。

限制

使用 __weak 限定函数和变量声明以及函数定义时,存在一些限制。

函数和变量声明

在同一编译中,不能既弱使用又非弱使用函数或变量。 例如,以下代码从 g()h() 中弱使用 f()


void f(void);

void g()

{

    f();

}



__weak void f(void);

void h()

{

    f();

}

无法从定义某个函数或变量的同一编译中弱使用该函数或变量。 以下代码从 h() 中非弱使用 f()


__weak void f(void);

void h()

{

    f();

}

void f() {}

链接器不会从库中加载函数或变量,除非其他编译非弱使用该函数或变量。 如果一直没有解析引用,则假定其值为 NULL。 但是,如果引用是指从代码中对与位置无关的节或缺少的 __weak 函数的引用,则未解析的引用不是 NULL

函数定义

无法内联弱定义的函数。

示例


 __weak const int c;            // assume 'c' is not present in final link

 const int *f1() { return &c; } // '&c' returns non-NULL if

                                // compiled and linked /ropi



 __weak int i;                  // assume 'i' is not present in final link

 int *f2() { return &i; }       // '&i' returns non-NULL if 

                                // compiled and linked /rwpi



 __weak void f(void);           // assume 'f' is not present in final link

 typedef void (*FP)(void);

 FP g() { return f; }           // 'g' returns non-NULL if 

                                // compiled and linked /ropi

另请参阅

Copyright © 2007 ARM Limited. All rights reserved. ARM DUI 0348AC
Non-Confidential