The #pragma weak directive prevents the link editor from issuing error messages if it does not find a definition for a symbol, or if it encounters a symbol multiply-defined during linking.
>>-#--pragma--weak--identifier--+----------------+------------->< '-=--identifier2-'
While this pragma is intended for use primarily with functions, it will also work for most data objects.
This pragma should not be used with uninitialized global data, or with shared library data objects that are exported to executables.
The dynamic linker will use the definition in whatever object appears first on the command line. Thus, the order in which the object files are presented to the linker is important.
Two forms of #pragma weak can be specified in your program source.
- #pragma weak identifier
- This form of the pragma defines identifier as a weak global symbol. References to identifier uses the identifier value if it is defined, otherwise identifier is assigned a value of 0.
If Identifier is defined in the same compilation unit as #pragma weak identifier, identifier is treated as a weak definition. If #pragma weak exists in a compilation unit that does not use or declare identifier, the pragma is accepted and ignored.
If identifier denotes a function with C++ linkage, identifier must be specified using the C++ mangled name of the function. Also, if the C++ function is a template function, you must explicitly instantiate the template function.
- #pragma weak identifier=identifier2
- This form of the pragma defines identifier as a weak global symbol. References to identifier will use the value of identifier2.
Identifier2 must not be a member function.
Identifier 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 identifier is declared in the compilation unit, identifier's declaration must be compatible to that of identifier2. For example, if identifier2 is a function, identifier must have the same return and argument types as identifier2.
Identifier2 must be declared in the same compilation unit as #pragma weak.
If identifier2 denotes a function with C++ linkage, the names of identifier and identifier2 must be specified using the mangled names of the functions. If the C++ function is a template function, you must explicitly instantiate the template function.
The compiler will ignore #pragma weak and issue warning messages if:
- If identifer2 (if specified) is not defined in the compilation unit.
- If identifer2 (if specified) is a member function.
- If identifer is declared but its type is not compatible with that of identifer2 (if specified).
The compiler will ignore #pragma weak and issue a severe error message if the weak identifier is defined.
// Begin Compilation Unit 1 #include <stdio.h> extern int foo; #pragma weak foo int main() { int *ptr; ptr = &foo; if (ptr == 0) printf("foo has been assigned a value of 0\n"); else printf("foo was already defined\n"); } //End Compilation Unit 1 // Begin Compilation Unit 2 int foo = 1; // End Compilation Unit 2If only Compilation Unit 1 is compiled to produce an executable, identifier foo will be defined and assigned the value 0. The output from execution will be the string: "foo has been assigned a value of 0."
//Begin Compilation Unit extern "C" void printf(char *,...); void foo1(void) { printf("Just in function foo1()\n"); } #pragma weak _Z3foov = _Z4foo1v int main() { foo(); } //End Compilation Unit