简体   繁体   中英

How can I implement a fallback function when some function is missing(at compile time)?

My goal is:

  1. if pthread_setname_np is defined in glibc, we will use glibc's version.
  2. otherwise, we will use a fallback function pthread_setname_np which actually do nothing to prevent compile errors.

This need to be done at compile time.

So I write the following codes

#include <cstdio>
#include <pthread.h>

__attribute__((weak)) int pthread_setname_np(pthread_t thread, const char *name) { printf("foo\n"); return 0; }

int main() {
    pthread_setname_np(pthread_self(), "bar");
}

IMO, if I run g++ test_free_bsd.cpp -o test_free_bsd -lpthread , since the symbol is already defined in pthread , so the compile will not link my self-defined symbol.

However, the program still prints out "foo", which means it actually uses my weak symbol.

Then it occurred to me that my self-defined pthread_setname_np is in the same unit with main , there are no linking. So I changed to the following

// g++ test_free_bsd.cpp test_free_bsd2.cpp -o test_free_bsd -lpthread
// test_free_bsd.cpp
#include <cstdio>
#include <pthread.h>

int main() {
    pthread_setname_np(pthread_self(), "bar");
}

// test_free_bsd2.cpp
#include <cstdio>
#include <pthread.h>
__attribute__((weak)) int pthread_setname_np(pthread_t thread, const char *name) { printf("foo\n"); return 0; }

However, the program still prints out foo . So I am lost here. IMO, in test_free_bsd.cpp, it will link pthread_setname_np in glibc, rather than in test_free_bsd2.cpp which is a weak symbol.

=== UPDATE ===

Why I wan to do this? There is a fallback in codes of Clickhouse . I am using these codes in my project, though I don't know why they are here. However, I don't want to change its behavior. I only want these lines to take effects only we are sure the glibc we linked to do not has pthread_setname_np .

On FreeBSD pthread_setname_np seems to exists, it is defined in pthread_setname_np.h . I don't know why you get a linker error (I can't test it.)

However, you should be able to use #ifndef _GNU_SOURCE around your pthread_setname_np to only define it if it isn't defined by pthread.h .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM