Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the symbol of member function weak?

Tags:

c++

symbols

gcc

I compiled this C++ code with g++ (7.3.0).

struct C {
  __attribute__((noinline)) int foo() { return 0; };
};

int bar(C &c) { return c.foo(); }

And using nm I found that foo is weak. Is that due to the C++ specification or a decision of GCC?

The experiment flow:

$ g++ test.cpp -c -Og  
$ nm test.o  
0000000000000000 T _Z3barR1C  
0000000000000000 W _ZN1C3fooEv
like image 677
eddie kuo Avatar asked Nov 19 '20 09:11

eddie kuo


People also ask

How do you define a weak symbol?

You can define a weak symbol using either the . weak assembly directive or the weak operator in the linker command file. Assemble the source file that defines weak symbols, and include the resulting object file in the link. The "ext_addr_sym" in this example is available as a weak symbol in a final link.

What is __ Attribute__ weak ))?

__attribute__((weak)) variable attributeGenerates a weak symbol for a variable, rather than the default symbol. extern int foo __attribute__((weak)); At link time, strong symbols override weak symbols.

What is strong and weak symbols in C?

For c program, if you define an global variable and not initialize it, GCC will regard it as weak symbol. However, for c++ program, the default type is strong variable. That is to say, for line int gvar; in main. cpp , it is a strong symbol. Since we have another strong symbol with the same name in aux.

What does __ weak mean in C?

The __weak keyword means that the function can be overridden by creating another function with the same declaration. Many of the interrupt-functions etc. in the STM HAL libraries are declared as weak so that you can override them with your own function, instead of modifying the library functions. From GCC Manual: weak.


1 Answers

Is that C++ specification or decision of GCC?

A bit of both. Not that the C++ specification deals with strong or weak symbols (it doesn't). But it does affect GCC's behavior, since usually extensions try to build upon standard mandated behavior.

When you define a member function in the class body, it's automatically an inline function. In the C++ language, an inline function is a function that can have multiple definitions, so long as they appear in different translation units. It's not a problem, because in C++, an inline function must have the exact same definition in every translation unit (down to the token sequence). So even though they are "different" definitions, they are identical, and so can be reduced to a single one at some point.

The function doesn't have to actually be inlined at the call site. As far as C++ is concerend, inline is about the one-definition rule and linkage. So you have that, there can be multiple definitions of C::foo according to the spec.

And then you specify __attribute__((noinline)), so the function cannot be physically inlined, and so every TU must contain a symbol for the function.

This leaves only one choice. The symbol must be weak, otherwise the different symbols in different translation units will interfere with eachother. By making the symbol weak, you can have your mandatory definition and avoid physically inlining the function, while the C++ specification is upheld. Those different symbols stand for the exact same function, and so any one of them can "win" when linking.

like image 52
StoryTeller - Unslander Monica Avatar answered Sep 27 '22 22:09

StoryTeller - Unslander Monica