Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this correct usage of weakref?

Tags:

c

gcc

I want to allow the redefinition of a function in a .c file that is already defined in a header file. According to GCC manual on the weakref attribute:

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.

Which sounds like exactly what I want to do. However, the following example does not compile with error:

tpp.c:18:13: error: redefinition of ‘foo’ tpp.c:6:13: note: previous definition of ‘foo’ was here

#include <sys/types.h>
#include <stdio.h>

/* this will be in a header file */
static void foo(void) __attribute__ ((weakref ("_foo")));

static void _foo(void)
{
    printf("default foo\n");
}

/* in a .c file #including the header mentioned above */
#define CUSTOM_FOO

#ifdef CUSTOM_FOO
static void foo(void)
{ 
    printf("user defined foo.\n");
}
#endif

int main(int argc, char **argv)
{
    printf("calling foo.\n");
    foo();
}

Am I using this correctly? What am I missing?

gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)

like image 953
Chris J. Kiick Avatar asked Nov 13 '22 14:11

Chris J. Kiick


1 Answers

As far as I understand that you need to define that function as extern. Then it work for me as follows:

user@horst:$ cat weakref.c

#include <sys/types.h>
#include <stdio.h>

/* this will be in a header file */
extern void foo(void) __attribute__ ((weak, alias ("_foo")));

void _foo(void)
{
    printf("default foo\n");
}

int main(int argc, char **argv)
{
    printf("calling foo.\n");
    foo();
}

user@horst:$ gcc weakref.c 
user@horst:$ ./a.out 
calling foo.
default foo
user@horst:$ cat weakrefUser.c
#include <stdio.h>
/* in a .c file #including the header mentioned above */
#define CUSTOM_FOO

#ifdef CUSTOM_FOO
void foo(void)
{ 
    printf("user defined foo.\n");
}
#endif
user@horst:$ gcc -c weakrefUser.c 
user@horst:$ gcc -c weakref.c 
user@horst:$ gcc weakref.o weakrefUser.o 
user@horst:$ ./a.out 
calling foo.
user defined foo.

Note1: It does not work with static functions, for the weak attribute, it need to be global.

Note2: Weak symbols are "only" supported for ELF targets.

like image 123
Willi Avatar answered Dec 07 '22 11:12

Willi