gcc: __attribute__ ((weak))

本文介绍了一种使用GCC扩展声明弱符号的技术,通过该技术可以在运行时检查符号是否已解析,从而实现按需线程安全的功能。此外,还讨论了函数指针的声明方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

While playing with glibc I noticed one interesting technique. It is
based on gcc's extension that allows you to declare weak symbols. In
essence it works like this:


extern void weak_f (void) __attribute__ ((weak));

int main ()
{
  if (weak_f)
  {
    weak_f ();
  }
}


When you link such code ld won't complain if weak_f is unresolved. 
Plus you can check at run-time if symbol has been resolved as shown 
above.

Interesting effects can be achieved using this technique. For example
you can make some code thread-safe on-demand. You compile this code
once and depending on kind of application it is used in it automatically
becomes multi-threaded or single-threaded:

#include <pthread.h>

extern "C" int
pthread_create (pthread_t*, 
                const pthread_attr_t*, 
                void* (*)(void*), 
                void*) __attribute__ ((weak));

extern "C" int
pthread_mutex_init (pthread_mutex_t*, 
                    const pthread_mutexattr_t*) __attribute__ ((weak));

extern "C" int
pthread_mutex_lock (pthread_mutex_t*) __attribute__ ((weak));

extern "C" int
pthread_mutex_unlock (pthread_mutex_t*) __attribute__ ((weak));

extern "C" int
pthread_mutex_destroy (pthread_mutex_t*) __attribute__ ((weak));


class foo
{
public:

  foo ()
  {
    if (pthread_create) pthread_mutex_init (&m_, 0);
  }
  
  ~foo ()
  {
    if (pthread_create) pthread_mutex_destroy (&m_);
  }


  bar ()
  {
    if (pthread_create) pthread_mutex_lock (&m_);

    // ...

    if (pthread_create) pthread_mutex_unlock (&m_);
  }

private:
  pthread_mutex_t m_;

  // some other data that mutex protects
};


Now if you link your code with libpthread, foo is automatically 
multi-thread-safe. If you don't then all the calls to mutex API 
are skipped.

This could be especially nice if class foo is in the library that
is used by both kinds of applications.

---------------------------

Function Pointer Syntax

The syntax for declaring a function pointer might seem messy at first, but in most cases it's really quite straight-forward once you understand what's going on. Let's look at a simple example:
void (*foo)(int);
In this example, foo is a pointer to a function taking one argument, an integer, and that returns void. It's as if you're declaring a function called "*foo", which takes an int and returns void; now, if *foo is a function, then foo must be a pointer to a function. (Similarly, a declaration like int *x can be read as *x is an int, so x must be a pointer to an int.) 

The key to writing the declaration for a function pointer is that you're just writing out the declaration of a function but with (*func_name) where you'd normally just put func_name. 

Reading Function Pointer Declarations

Sometimes people get confused when more stars are thrown in:
void *(*foo)(int *);
Here, the key is to read inside-out; notice that the innermost element of the expression is *foo, and that otherwise it looks like a normal function declaration. *foo should refer to a function that returns a void * and takes an int *. Consequently, foo is a pointer to just such a function.

The argument expected by pthread_create is,

void *(*)(void *)

that is a pointer to function accepting a void pointer and returning a void pointer.





__attribute__((weak))是一个GCC编译器的特性,用于声明函数或变量为弱符号引用。在使用该特性时,可以在调用某个模块的函数时,即使该函数在该模块中未定义也不会报重复定义的错误。 举个例子,如果在模块A中调用了模块B的函数,但是模块B的函数可能未定义,可以在模块A中使用__attribute__((weak))来声明需要调用的函数为弱符号引用。这样,在模块A的代码中,可以通过检查该函数的指针是否为NULL来判断该函数是否存在,从而避免因为函数未定义而导致的错误。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [ARM 之十一__weak 代码 WEAK.7z](https://download.youkuaiyun.com/download/ZCShou优快云/12572659)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [__attribute__系列之__attribute__((weak))](https://blog.youkuaiyun.com/weixin_45367955/article/details/130532947)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [__attribute__((weak))介绍以及用法](https://blog.youkuaiyun.com/weixin_42031299/article/details/116269010)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值