开发者

In C++ how is function overloading typically implemented?

开发者 https://www.devze.com 2022-12-19 09:43 出处:网络
If there is no function overloading, the function name开发者_Go百科 serves as the address of the function code, and when a function is being called, its address is easy to find using its name. However

If there is no function overloading, the function name开发者_Go百科 serves as the address of the function code, and when a function is being called, its address is easy to find using its name. However with function overloading, how exactly can the program find the correct function address? Is there a hidden table similar to virtual tables that stores the overloaded functions with their address? Thanks a lot!


Name mangling.

It's all done at compile time. The C++ compiler actually modifies the function names you give it internally, so that a function like

int foo(int a, float b, char c) 

internally gets a name equivalent to

func_foo_int_float_char()

(the real symbol is usually some gobbledygook like ?CFoo@Foo@@QAAX_N@Z ).

As you can see, the name is decorated depending on the exact number and types of parameters passed. So, when you call a function, it's easy for the compiler to look at the parameters you are passing, decorate the function name with them, and come up with the correct symbol. For example,

int a, b; float f; char c;
foo(a,f,c) ; // compiler looks for an internal symbol called func_foo_int_float_char
foo(a,b,c) ; // compiler looks for a symbol called func_foo_int_int_char

Again, it's all done completely at compile time.


The compiler can look at the call, and match that against the known existing overloaded implementations, and pick the right one. No need for a dynamic table, it's all perfectly doable statically at compile-time.

Update: removed my attempt at illustrating the concept by showing differently-named functions that the compiler can choose between.


If you are talking about overloaded methods of the same class, like so:

void function(int n);
void function(char *s);
...

objectInstance->function("Hello World")  

It is a compile time thingy. The compiler knows (or in some situations, makes a best guess) at this point which method to call.

A comment I made in the question, I repeat here.

People who suggest name mangling are misguided I think. It is not as if the compiler mangles the name and just does a lookup among the mangled names. It needs to infer the proper types from the available methods. Once it does that, it already knows which method to call. It then uses the mangled name as the last step. Name mangling is not a prerequisite for determining which overloaded function to call.


Overloaded functions are resolved at compile-time. The compiler finds a suitable match for the given set of parameters and simply calls the corresponding function by its address (void foo(int) and void foo() are practically two totally independent functions - if you have foo(4) in your code, the compiler knows which function to call).


It is, I believe, achieved through name mangling:

the functions you know as foo(int) and foo(double) are actually named something like int_foo() and double_foo() (or similar, I'm not entirely sure of the particular semantics employed for C++). This means that C++ symbols are usually an order of magnitude larger than the names they are given in code.


C++ compilers use name mangling (different name for each overload) to distinguish between the functions in the object file. For example

int test(int a){}
int test(float a,float b){}
int test(double a){}
int testbam(double a){}

would produce the symbol names __Z4testi, __Z4testff, __Z4testd, __Z7testbamd. This name mangling is highly compiler-dependent (sadly) and one of many reasons why often C is preferred over C++.

When calling the function test, the compiler matches the given argument types and number of arguments against each function overload. The function prototypes are then used to find out which one should be called.


The function signature is composed of the function name + parameter(s) type(s)


Even if no function overload, compilers usually mangle function and variable names. It is called name mangling. It happens in both C and C++. Function name can be decorated by notably (1) calling convention, (2) C++ function overloading, (3) class member function.

GNU binutil c++filt can undecorate this mangled name, and in Windows, there is UnDecorateSymbolName

0

精彩评论

暂无评论...
验证码 换一张
取 消