Strong And Weak Symbol

While I was writing my last article, I found a .weak label in assembly program. According to http://downloads.ti.com/docs/esd/SPNU118/weak-symbols-sprui029023.html, it is the same as #pragma weak in C/C++.

What is weak symbol

The definition of weak symbol in C and C++ is different:

What properties does it have

Simply put, it allows functions or variables with the same name to be multiple defined in multiple files, as long as:

Consider we have such program:

// test.cpp
#pragma weak ijkkl
float ijkkl = 10000;
void printType(){
    std::cout << typeid(ijkkl).name() << std::endl;
}
// main.cpp
#pragma weak ijkkl
using namespace std;
int ijkkl = 10;
extern void printType();
int main() {
    cout << typeid(ijkkl).name() << endl;
    printType();
}

What is the actual size of variable ijkkl?

The answer is the size of float (in 64 machine, size of float is the same as size of int, but you know what I mean), we can check it by checking the binary memory view of the program.

What is the output of this program?

The answer is i indicate to int, and then f indicate to float.

So in conclusion, if we have multiple weak definition of a variable, the actual size of it will depends on the first linked file, and for each file that contain this variable, they think the variable’s type and size is the same as the definition in their own file. In this case, because float and int are encoded in different way, the output will be unreadable, so I suggest trying not to cause such confusion.

For weak symbol function, the actual function in the memory depends on the first linked file, and for each file that contain this function, they think the return type (parameter type is not included, since that will trigger function overload) of the function is the same as the definition in their own file. Which means if you have different definition of a function in different files, you might be unable to obtain the return value correctly.

No matter what kind of weak symbol it is, if it is undefined (no strong symbol with the same name in the whole project), it will be set to 0, so we have below good example:

A useful example

// test.cpp
#include <iostream>
int printType(){
    printf("Hello test\n");
    return 1129387;
}
// main.cpp
#include <iostream>
using namespace std;
int   printType();

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

In main.cpp, we test if printType equal to 0, if there isn’t a strong definition for this function, it will be set to 0.