#pragma weak

Category

Object code control

Purpose

Prevents the linker from issuing error messages if it encounters a symbol multiply-defined during linking, or if it does not find a definition for a symbol.

The pragma can be used to allow a program to call a user-defined function that has the same name as a library function. By marking the library function definition as "weak", the programmer can reference a "strong" version of the function and cause the linker to accept multiple definitions of a global symbol in the object code. While this pragma is intended for use primarily with functions, it will also work for most data objects.

Syntax

Read syntax diagramSkip visual syntax diagram
>>-#--pragma--weak--name1--+----------+------------------------><
                           '-=--name2-'   

Parameters

name1
A name of a data object or function with external linkage.
name2
A name of a data object or function with external linkage.

name2 must not be a member function. If name2 is a template function, you must explicitly instantiate the template function.

Usage

There are two forms of the weak pragma:
#pragma weak name1
This form of the pragma marks the definition of the name1 as "weak" in a given compilation unit. If name1 is referenced from anywhere in the program, the linker will use the "strong" version of the definition (that is, the definition not marked with #pragma weak), if there is one. If there is no strong definition, the linker will use the weak definition; if there are multiple weak definitions, it is unspecified which weak definition the linker will select (typically, it uses the definition found in the first object file specified on the command line during the link step). name1 must be defined in the same compilation unit as #pragma weak.
#pragma weak name1=name2
This form of the pragma creates a weak definition of the name1 for a given compilation unit, and an alias for name2. If name1 is referenced from anywhere in the program, the linker will use the "strong" version of the definition (that is, the definition not marked with #pragma weak), if there is one. If there is no strong definition, the linker will use the weak definition, which resolves to the definition of name2. If there are multiple weak definitions, it is unspecified which weak definition the linker will select (typically, it uses the definition found in the first object file specified on the command line during the link step).

name2 must be defined in the same compilation unit as #pragma weak. name1 may or may not be declared in the same compilation unit as the #pragma weak, but must never be defined in the compilation unit. If name1 is declared in the compilation unit, name1's declaration must be compatible to that of name2. For example, if name2 is a function, name1 must have the same return and argument types as name2.

This pragma should not be used with uninitialized global data, or with shared library data objects that are exported to executables.

Examples

The following is an example of the #pragma weak name1 form:
// Compilation unit 1:

#include <stdio.h>

void foo();

int main()
{
       foo();
}

// Compilation unit 2:

#include <stdio.h>


#pragma weak foo

void foo()
{
       printf("Foo called from compilation unit 2\n");
}

// Compilation unit 3:

#include <stdio.h>

void foo()
{
       printf("Foo called from compilation unit 3\n");
}                
If all three compilation units are compiled and linked together, the linker will use the strong definition of foo in compilation unit 3 for the call to foo in compilation unit 1, and the output will be:
Foo called from compilation unit 3
If only compilation unit 1 and 2 are compiled and linked together, the linker will use the weak definition of foo in compilation unit 2, and the output will be:
Foo called from compilation unit 2
The following is an example of the #pragma weak name1=name2 form:
// Compilation unit 1:

#include <stdio.h>

void foo();

int main()
{
foo();
}

// Compilation unit 2:

#include <stdio.h>

void foo(); // optional

#pragma weak foo = foo2

void foo2()
{
printf("Hello from foo2!\n");
}

// Compilation unit 3:

#include <stdio.h>

void foo()
{
printf("Hello from foo!\n");
}        
If all three compilation units are compiled and linked together, the linker will use the strong definition of foo in compilation unit 3 for the call to foo from compilation unit 1, and the output will be:
Hello from foo!
If only compilation unit 1 and 2 are compiled and linked together, the linker will use the weak definition of foo in compilation unit 2, which is an alias for foo2, and the output will be:
Hello from foo2!

Related information