In depth: macros inline functions and ordinary functions of the difference

  • 2020-04-02 00:51:49
  • OfStack

The execution of inline functions is similar to the macro definition with arguments, but the parameters are handled differently. Macro definitions with arguments do not evaluate the arguments, but replace them directly
; An inlined function is a function, which means that many of the properties of a function apply to an inlined function, that is, an inlined function evaluates an argument expression
Then pass the value of the expression to the formal parameter.
      Another difference between inline functions and macro definitions with arguments is that the argument types and return value types of inline functions are explicitly specified in the declaration. The parameters
There is no notion of a type for the parameters of a macro definition, and the compiler checks the syntax only after the macro has been expanded, which presents a number of security concerns.
      When using inline functions, note the following:
      1) the definition declaration of an inline function should appear before the first call to the function.
      2) inline functions are functions. Many properties of functions are applicable to inline functions. For example, inline functions can be overloaded.
      3) loop statements and switch results are not allowed in inline functions, and functions with exception interface declarations cannot be declared as inline functions.
First, the difference between macros and functions:
Macro is a simple string replacement (note that is the replacement of the string, not the replacement of other types of parameters), and the function of the parameters, parameters are the data class
Type, can be a variety of types.
2. The parameter replacement of macro is directly handled without calculation, while the function call is to pass the value of the argument to the parameter.
Macro before compilation, that is, replace the macro name with the macro body, and then compile, and the function is obviously compiled, in the execution, only called
Is the compilation time, and the function is the execution time.
4. Macro parameters do not occupy the memory space, because it is only to do the string replacement, and the function call when the parameter is the specific variables between the information transfer, formal parameters
As a local variable of a function, it is clearly a memory hog.
5. The call of the function needs to pay a certain amount of time and space overhead, because the system should keep the scene when calling the function, and then transfer to the called function to execute, after the call,
Return to the main function, then restore the scene, these operations, obviously in the macro is not.
Now for inline functions:
An "inline function" is a simple function that is "embedded" in the code that calls it, just to avoid point 5, the purpose
In order to save the time and space overhead of the original function call, it is important to note that as an inline function, the body of the function must be very simple and must not contain loops, conditions, or choices
Otherwise it can't be an inline function. In fact, even if you don't specify an inline function, some compilers will automatically be very simple
Single functions are treated as inline functions; For complex functions, even if you specify it as inline, the system won't care.

Before introducing inline functions, it's worth introducing preprocessor macros. Inline functions and preprocessor macros
Similar functionality. I'm sure you've all used preprocessor macros, and we'll often define macros such as
# define TABLE_COMP (x) (x) > 0? (x) : 0)
Defines a macro.

Why use macros? Because function calls must transfer the order of program execution to the function
An address stored in memory that executes the program contents of the function and then returns to execute
Before the function. This transfer operation requires the site to be saved and the place to be memorized before being transferred for execution
Address, return to the site to restore, and according to the original save address to continue to execute. Therefore, the function call has to have one
Fixed time and space costs, then will affect its efficiency. And the macro is just in the preprocessing place
Code expansion requires no additional overhead in terms of space and time, so calling one macro is better than calling one macro
Functions are more efficient.

But macros also have a lot to be desired.
1). Macros cannot access private members of an object.
2). The definition of a macro is easily ambiguous.
Here's an example:
* x # define TABLE_MULTI (x) (x)
We're going to call it TABLE_MULTI(10) with a number, so it looks like there's nothing wrong,
The result returns 100, which is correct, but if we call it TABLE_MULTI(10+10),
We expect the result to be 400, and the macro call to be (10+10*10+10), which is 120
But that's not what we want. One way to avoid these errors is to bracket the arguments of a macro.

# define TABLE_MULTI (x) (x) * (x))
 
This ensures that nothing goes wrong, but even with this definition, the macro is still possible
Error, such as calling it with TABLE_MULTI(a++), they want to get (a+1)*(a+1)
As a result, as a matter of fact? We can look at the macro expansion result: (a++)*(a++), if the value of a is
4, we get 5 times 6 is equal to 30. And we're expecting 5 times 5 is 25, and that's a problem again.
In fact, some of the C library functions have these problems as well. For example: Toupper(* pg ++) will be right
PChar performs the ++ operation twice, because Toupper is actually a macro as well.

We can see that macros have some unavoidable problems. How to solve them?
 
So here's how to solve these problems with the inline functions that I'm going to introduce, which we can use
To replace the definition of macros. And in fact we can completely replace preprocessor macros with inline functions.

The difference between inline functions and macros is that macros are replaced by preprocessors, whereas inline functions are
Through compiler control to achieve. And an inline function is a real function, only if it's needed
The inline function expands like a macro, so it cancels the argument stack of the function and reduces the opening of the call
Pin. You can call an inline function just as you would a function without worrying about one of the macros
Some problems.
We can define Inline functions with Inline, however, any function defined in the description section of the class
Numbers are automatically considered inline.

Now let's introduce the use of inline functions.
 
An inline function must be declared with the body of the function to be valid. Statements like this
Inline Tablefunction(int I) has no effect, and the compiler simply treats the function as a normal function
Number statement, we must define the body of the function.

Inline tablefunction(int I) {return I*I};
 
So we've defined an inline function. We can tune it as a general function
To use. But it does execute faster than normal functions.

We can also define functions defined outside the class as inline functions, such as:
 
Class TableClass{
 Private:
  Int I,j;
 Public:
  Int add() { return I+j;};
  Inline int dec() { return I-j;}
  Int GetNum();
}
inline int tableclass::GetNum(){
return I;
}
 
All three functions declared above are inline. In C++, the body of a function is defined inside a class
Function, which by default is an inline function. Regardless of whether you have the inline keyword or not.

Inline functions are most commonly used in C++ classes to define access functions. We define
Classes typically define data members as private or protected, so that the outside world cannot read or write to me directly
Data for class members.
      Private or protected members must be read and written using the member interface function. If we take
If these read-write member functions are defined as inline functions, they will be more efficient.
 
Class sample{
 Private:
  Int nTest;
 Public:
  Int readtest(){ return nTest;}
 Void settest(int I) {nTest=I;}
}
 
Of course, there are limitations to inline functions. You can't have too much execution in the function, for example
If the body of an inlined function is too large, the general compiler will abandon inlining in favor of the general method
Call the function. In this way, the inline function is as efficient as the normal function.

 
The use of macros
/* this series of articles "C++ Tips" is recommended by the company's Code Committee experts to the engineers, it feels good, take out with everyone to improve. Don't
It's knowing how much makes a difference. The real difference is how much you can do.
Many programmers don't know what "macro" in C really means. Macros are often confused with functions, especially when they have arguments. I think I'm still here
A macro is just a definition that defines a block of statements that the compiler first performs to "replace" the source program when it compiles
, replace the place the macro refers to with the statement block of the macro definition, just like a text file replacement. The action term is "macro expansion." Using macros is more dangerous
Close "because you don't know what the macro will look like when it expands. For example, the following macro:
    # define MAX (a, b) a > B? A: b
When we use macros like this, there's no problem: MAX(num1, num2); Because the macro expands to become num1 > Num2? Num1: num2; . But, as
So this is MAX(17+32, 25+21); There was an error at compile time because the macro expanded to: 17+32 > 25 + 21? 17 + spake + 21,
Woh, what is this?
So, when macros are used, the arguments must be parenthesized. The above example can be changed to look like this to solve the problem.
    Define MAX((a), (b)) (a) > (b)? (a), b)
Even so, this macro is still buggy, because if I call MAX(i++,j++) like this; After this macro, I and j are added up to two
This is not what we want. Therefore, use macros with caution, because macros are hard to predict. And although,
Macros execute quickly (because there is no overhead for function calls), but macros cause the source code to expand, making the target file larger (e.g., a 50-line macro, program)
It is used in 1000 places, which is very bad when the macro is expanded), and it does not make the program execute faster (because the execution file is larger and the run-time system changes pages frequently)
).
Therefore, be careful when deciding whether to use functions or macros.
 
Inline function definitions in C++ are as simple as adding a keyword inline before normal functions, and otherwise nothing on the surface of normal functions
The difference (including the way the function is called) is that inlining seems to many C++ beginners (and even some with C++ programming experience)
It's just a concept, it's not a complete understanding of inline functions, so let's talk about the difference between inline functions and ordinary functions and macros, phase
The letter After reading the following sections, you must have a good understanding of all three.
            The biggest difference between an inline function and a normal function is the internal implementation, not the surface form, and we know that an ordinary function, when it's called, the system
The first step is to jump to the entry address of the function, execute the body of the function, and then return to the place where the function is called. There is always only one copy of the function. while
An inlined function does not require an addressing process, and when executed to an inlined function, the function expands (much like the use of macros) if called at N
Inline function, the function will have N copies of the code.
            From the point of view of calling inline functions, it makes the code more efficient by eliminating an addressing process, but at the cost of space
.
            For functions declared inline, the code segment cannot be too long, and some compilers treat it as a normal function.
This does not seem to be specified, this is really not specified, the individual should be decided by the logic of the function body).
          Here is an example of an inline function declaration:
        Inline void SetVal(int a){m_b = a};
        Inline int GetVal(){return m_b};
        As you can see from the above example, the declaration and implementation of inline functions are usually in one file (usually in. H).
        Now let's talk about the difference between inline functions and macros. In a lot of materials, when we talk about inline functions, we say that inline functions are very similar to macros, but classes
After all, we can't use them interchangeably.
        The similarity between the two is that the compiler handles them at execution time, unrolling their code and continuing the process after execution. The difference is in macros
It's a simple text substitution, it doesn't return a value, it doesn't have the concept of a generic function argument; Inline functions have the characteristics of normal functions, such as parameter lists,
Return value, etc. Here's an example:
        1.#define COUNT(X)(X * X) // a macro to calculate the product
        Return x*x} // an inline function to calculate the product
     
        Printf (COUNT (3)); // the result is COUNT(3) (3 * 3) = 9;
        Printf (count (3)); // the result is count(3){return 3*3}=9;

        The above example doesn't seem to be enough to explain the difference between the two, so let's change the invocation of the above example and see the result

        Printf (COUNT (2 + 3)); // this is going to be COUNT(2+3)(2+3 * 2+3) = 11
        Printf (count (2 + 3)); // the result is count(2+3){return 5*5; } = 25;

        If the macro is to reach the product of 25, it should be written like this:
        # define the COUNT (X) (X) * (X))
        The corresponding example is #define COUNT(2+3)(2+3)*(2+3).

Related articles: