[C++ Basic Study Notes] In-depth understanding of C++ function overloading (very important!!!)

[High-frequency interview questions]
1. Can the following two functions form function overloading? Is there a problem or under what circumstances?

void TestFunc(int a = 10)
{
    
    
	cout << "void TestFunc (int) " << endl;
}
void TestFunc(int a)
{
    
    
	cout << "void TestFunc(int) " << endl;
}

2. Why can't function overloading be supported in C language?
3. How to deal with function overloading at the bottom
in C++? 4. Can a function be compiled in C style in C++?
These questions, I believe you read the blog There will be an answer in your mind.



function overloading

Interesting little story: In natural language, a word can have multiple meanings, and people can judge the true meaning of the word through context, that is, the word is overloaded.
For example: There was a joke in the past that you don't need to watch or worry about two state-owned sports. One is table tennis and the other is men's football. The former is "No one can win!" (No one can win), and the latter is "No one can win!" (No one can win) (Chinese culture is really broad and profound, and the sentence here is not necessarily correct, friends. You can try it yourself)

The concept of function overloading

Function overloading is a special case of functions. C++ allows several functions of the same name with similar functions to be declared in the same scope. The formal parameter lists (number or type or order of parameters) of these functions with the same name must be different. It is often used to deal with implementation. Problems with similar functions and different data types

Example:

#include<iostream>
using namespace std;
int Add(int x, int y)
{
    
    
	return x + y;
}
double Add(double x, double y)
{
    
    
	return x + y;
}
long Add(long x, long y)
{
    
    
	return x + y;
}
int main()
{
    
    
	cout << Add(1, 2) << endl;
	cout << Add(1.1, 2.2) << endl;
	cout << Add(10L, 20L) << endl;
	return 0;
}

insert image description here


Think, do the following two functions constitute function overloading?

int Add(short x, short y)
{
    
    
	return x + y;
}
short Add(short x, short y)
{
    
    
	return x + y;
}

Answer: Does not constitute function overloading, does not meet the conditions of function overloading, function overloading does not consider the difference in return value type, the compiler will report an error when compiling.

insert image description here

Understanding:
overloading, that is, polysemy
Function overloading: the same function name can represent multiple different functions

Requirement: The function name is the same, the parameters are different (the parameters are different in the following three aspects: different types, different numbers, different orders, one of them can be satisfied), but there is no requirement for the return value (if only the return value is different, then Can not constitute overloading)
C language stipulates that the function names cannot be the same, but in C++ the function names can be the same, because C++ supports function
overloading. The application of function overloading, the function call will automatically identify the parameter type


name mangling

Why does C++ support function overloading, but C language does not support function overloading?
For the convenience of demonstration, create corresponding files and codes under linux:
insert image description here

//list.h
#include<stdio.h>
void list_push_back(int x);
void add(int i, int j);
int add(double i, double* j);
//list.c
#include"list.h"
void list_push_back(int x)
{
    
    
	printf("%d\n", x);
}
void add(int i, int j)
{
    
    }
int add(double i, double* j)
{
    
    
	return 0;
}
//test.c
#include"list.h"
int main()
{
    
    
	list_push_back(1);
	return 0;
}

If we directly use the gcc compiler (c language compiler) to compile the above code, it will definitely fail to compile, because there is function overloading
insert image description here
. If you comment out the function overloaded part before
insert image description here
compiling, there should be no problem. , and at the same time we compile it with the c++ compiler g++, and get:
insert image description here
using xshell to open multiple windows at the same time, you can quickly modify
insert image description here

In C/C++, to run a program, it needs to go through the following stages:
preprocessing, compilation, assembly, and linking.
Source file in c language: test.c (ending with .c, English: source) C++ source file: test.cpp (ending with .cpp, English: c-plus-plus)
preprocessing -> header file expansion, macro replacement , Conditional compilation, remove comments to generate list.i test.i
compile -> check syntax, generate assembly code to generate list.s test.s
assembly -> convert assembly code to binary machine code to generate list.o test.o
link - linking the two object files together produces the executable test.exe

The above two stages of assembly and linking are the key to our understanding of function overloading, especially the linking stage
insert image description here
. If it is found, it will be linked normally to generate an executable program .exe file. If it cannot be found, a link error will occur.
When will it not be found?
When we declare a function and then call it normally, but it is not defined, then the address of this function cannot be found.

In the C language, in the symbol table generated by the assembly, it can be found that the corresponding function name modification has not changed. If there are two functions with the same name, which function address should be found and used when calling the function at link time? ? Is it indistinguishable, which is why C language does not support function overloading (the modification of the function name after assembly has not changed)

insert image description here
What about C++? What is the situation? Why support function overloading? Could it be that the decorated name of the function has changed?
insert image description here
Remove the previously generated cpp first, then uncomment the previously commented code segment, and regenerate the cpp file.
insert image description here
Use the objdump -S command to view the information about the symbol table.
insert image description here
Find the symbol table of the three functions of list_push_back, add, and add, and
insert image description here
you can see that it has been added. Some modified content, such as Z14 / _Z3 in the front, ii, dPd in ​​the back), so even if the function name is the same, but the function parameters are different, the generated symbol table will be different. When calling, according to the generated symbol table, you can still Find the corresponding function address, there will be no conflict and can be distinguished, so overloading is supported!
insert image description here
<_Z3Addii> _Z3 is the prefix Add is the function name, ii (i is the first letter of the type) refers to two parameters of type int
insert image description here
C language format
insert image description here

Summary: C++ and C function name modification rules are different. The function name modification rules of C++ will introduce parameter-related information. Therefore, when the function name is the same and the parameters are different, the names generated by the function name modification rules are also different. , you can distinguish between the same function name! The function name modification rule of C language is to use the function name directly, which has nothing to do with the function parameters. If a function with the same name appears, then when the function is called when linking, which one should be called? Two names are exactly the same, there is no way to determine which one to call!

insert image description here

1. In fact, our project is usually composed of multiple header files and multiple source files, and through the compilation link we learned in the C language stage, we can know that [the Add function defined in b.cpp is currently called in a.cpp When], before linking after compilation, there is no function address of Add in the object file of ao, because Add is defined in b.cpp, so the address of Add is in bo. So what should we do?
⒉ Therefore, the linking stage is specially to deal with this kind of problem. The linker sees that ao calls Add, but there is no address of Add, it will go to the symbol table of bo to find the address of Add, and then link them together.
3. When linking, in the face of the Add function, which name will the linker use to find it? Here, each compiler has its own function name modification rules.
4. Since the modification rules of vs under Windows are too complicated, while the modification rules of gcc under Linux are simple and easy to understand, we use gcc to demonstrate the modified name below.
5. From the following we can see that the name of gcc's function is unchanged after modification. The g++ function modification becomes [_Z + function length + function name + type first letter].
6. Through this, I understand that the C language cannot support overloading, because the functions of the same name cannot be distinguished. C++ is distinguished by function modification rules. As long as the parameters are different, the modified names are different, and overloading is supported.
7. In addition, we also understand why function overloading requires different parameters! It has nothing to do with the return value.


extern “C”

Sometimes in a C++ project, it may be necessary to compile some functions according to the C style, adding extern "C" before the function, which means to tell the compiler to compile the function according to the rules of the C language. For example: ttmlloc is a project implemented by google in C++. It provides two interfaces, tcmallc() and tcfree, for use, but if it is a C project, it cannot be used, so he uses extern "C" to solve it.
Static library and dynamic library
insert image description here
In order to make C++ and C++ programs can use this C++ static library/dynamic library, you can use extern "C"
insert image description here

C++ is compatible with the rules of C language. After extern "C" is used, function overloading is not supported, because at this time, the symbol table is generated according to the rules of C language.


Let's review the four interview questions mentioned at the beginning. After reading my secret notes, I believe you should know something about it~

[High-frequency interview questions]
1. Can the following two functions form function overloading? Is there a problem or under what circumstances?

void TestFunc(int a = 10)
{
    
    
	cout << "void TestFunc (int) " << endl;
}
void TestFunc(int a)
{
    
    
	cout << "void TestFunc(int) " << endl;
}

2. Why can't function overloading be supported in C language?
3. How is function overloading in C++ handled at the bottom?
4. Can a function be compiled in C style in C++?

Guess you like

Origin blog.csdn.net/QIYICat/article/details/119786258
Recommended