18

If there is no function overloading, the function name 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!

6
  • 6
    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. Commented Feb 9, 2010 at 8:34
  • Maybe this comment should go in one of the misguided answers you're referring to? Commented Feb 9, 2010 at 8:37
  • There are too many, so I left it here. Commented Feb 9, 2010 at 8:39
  • 2
    Entirely true. Given void foo(int); and void foo(std::string);, foo(1.0f) will call the first. The "name mangling" suggestions would have the compiler look for ? foo(float) and fail. Commented Feb 9, 2010 at 9:19
  • If you want the address of an overloaded function, sometimes you have to cast that address to the appropriate type. Suppose you have two functions foo, one taking an int and one taking a float, and you want the address of the one taking an int, you write static_cast<void(*)(int)>(&foo). Commented Feb 9, 2010 at 11:00

8 Answers 8

13

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.

Sign up to request clarification or add additional context in comments.

1 Comment

It's the other way round. The compiler first looks at all foos, chooses one which matches according to all the rules in the standard, and then perhaps emits a mangled name for the linker.
12

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.

8 Comments

People say this techniq Name Mangling. Search this keyword.
Name mangling is just to differentiate between names of identifiers, overloaded or not. The main purpose of name mangling is not to cater to overloading, but to avoid naming conflicts. In the overloaded case, the compiler has to work out which method to call and that is where the main logic is. I believe the OP wanted to know if this was a compile time/runtime thing.
That's not accurate, it is usually the linker that needs to calculate the call address. Name decoration very much matters. Yes, there is an opportunity to omit the link request if the function happens to be located in the same translation unit. Whether that actually happens is an implementation detail.
@unwind: So what happens if I call foo(1.0)? The compiler looks for void fo_double(double z) which doesn't exist. As others have said, name mangling isn't the answer.
@nobugz: The compiler can determine which method to call and generates the right function name (whether it be mangled or not) which the linker then uses. You are saying the same thing I said. Mangled names are just one of solutions to avoid conflicts during linking time. They are not required for providing function overloading. Function overloading features might change the way the names are mangled, but that is just a corollary of having unique names.
|
7

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.

5 Comments

To the person who gave a -1. At least leave a comment. I can either delete/edit the post if the information is inaccurate. Give me a chance to learn too!
I guess that person (not me) downvoted because you didn't really give a clear answer. Instead you just say "compile time" and "the compiler just knows what to do", which is indeed a bit inaccurate.
Well, name mangling is inaccurate, IMO. The best we can say is the "compiler knows". Each compiler might have its own implementation.
Name mangling helps (is, so far as I know, needed by) the linker.
You could also copy your comment to unwind, as you expose a different use of name mangling that is interesting.
3

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).

Comments

0

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.

Comments

0

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.

Comments

-1

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

Comments

-1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.