On the difference between inline function and macro definition _c language

Source: Internet
Author: User
Tags assert function definition
Replace macros with inline:
1. Inline functions can be debugged at run time, while macro definitions are not possible;
2. The compiler will do security checks or automatic type conversions (with normal functions) on the parameter types of the function, while the macro definition will not;
3. The inline function can access the member variables of the class, and the macro definition cannot;
4. Declare a member function defined at the same time in a class and automatically convert to an inline function.
article (i)
Inline functions and macro definitions
In C, the common preprocessing statement #define to replace a function definition. For example:
#define MAX (A,b) ((a) > (b)? ( A):(B))
This statement causes every occurrence of the max (A,B) function call in the program to be followed by the expression in the macro definition ((a) > (b)? ( A) replaced by:(B)).
The writing format of a macro definition statement is overly fastidious, there should be no spaces between Max and parentheses, all parameters must be
Put it in parentheses. Still, it's a problem:
int a=1,b=0;
MAX (a++,b);//a is added 2 times
MAX (a++,b+10);//a is added 1 times
MAX (A, "Hello");//incorrectly compare int and string, no parameter type check
The value of the MAX () function can have different side effects because of the size of the two parameter values.
The value of MAX (A++,b) is 2, while the value of a is 3;
The value of MAX (A++,B+10) is 10 and the value of a is 2.
If it is a normal function, Max (A, "HellO") is checked by the function call, but it is not rejected because the two parameter types are different. Fortunately, an inline function can be used to get all the substitution effectiveness and all predictable states of the macros as well as the type checking of the regular functions:
inline int MAX (int a,int b)
{
Return a>b?a:b;
}
1. The difference between inline functions and macros:
Traditional macro-definition functions can cause some problems.
Ex
#define F (x) x+x
void Main () {int i=1; F (i++);}
Here X will be added two times.
Inline functions are automatically added to the code by the compiler using the situation of the function without this occurrence.
The use of inline functions improves efficiency (eliminating many function invocation assembly code such as call and RET, etc.).
2. Use of inline functions:
All functions defined in the declaration of a class are automatically considered to be inline functions.
Class A ()
{
void C ();/not a inline function;
void D () {print ("D () is a inline function.");}
}
If you want to define a global function as an inline function, inline the keyword.
Inline A () {print ("A () is a inline function.");}
Note:
If there are complex operations in inline functions, they will not be inline. such as: loops and recursive calls.
Summary:
Defining a simple short function as an inline function increases efficiency.

Article (ii)
8.5.1 replaces macro code with inline
The C + + language supports the function inline, which is designed to improve the execution efficiency (speed) of the function.
In the C program, you can use macro code to improve execution efficiency. The macro code itself is not a function, but it is used as a function. The preprocessor replaces the function call by copying the macro code, eliminating the parameter stack, generating the call invocation of assembly language, returning parameters, executing return, and so on, thus increasing the speed. The biggest disadvantage of using macro code is error-prone, and the preprocessor often produces unexpected marginal effects when replicating macro code. For example
#define MAX (A, B) (a) > (b)? (a): (b)
Statement
result = MAX (i, J) + 2;
will be interpreted by the preprocessor as
result = (i) > (j)? (i): (j) + 2;
Because the operator ' + ' operator ': ' has a higher precedence, the above statement is not equivalent to the expected
result = ((i) > (j)? (i): (j)) + 2;
If you rewrite the macro code to
#define MAX (A, B) ((a) > (b)? (a): (b))
You can resolve the error caused by the priority. But even using the modified macro code is not foolproof, such as a statement
result = MAX (i++, J);
will be interpreted by the preprocessor as
result = (i++) > (j)? (i++): (j);
For C + +, there is another drawback to using macro code: You cannot manipulate private data members of a class.
Let's take a look at how the C + + function inline works. For any inline function, the compiler puts a function declaration (including first name, parameter type, return value type) in the symbol table. If the compiler does not find any errors in the inline function, the code for the function is also placed in the symbol table. When an inline function is invoked, the compiler first checks to see if the call is correct (type security check, or automatic type conversion, of course, all functions are the same). If correct, the code for the inline function replaces the function call directly, eliminating the overhead of the function call. This process differs significantly from preprocessing, because the preprocessor cannot perform type security checks or perform automatic type conversions. If the inline function is a member function, the address (this) of the object is placed in the appropriate place, which is not what the preprocessor can do.
The function-inline mechanism of C + + language has both the efficiency of macro code and security, and it can manipulate the data members of the class freely. So in C + + programs, you should use inline functions instead of all the macro code, "assert assert" I am afraid is the only exception. An assert is a macro that works only in the debug version and is used to check for situations where "should not" occur. In order not to cause differences in the debug and release versions of the program, the assert should not have any side effects. If assert is a function, it will cause a difference between the debug version and release version because the function call can cause memory and code to change. So assert is not a function, but a macro. (See section 6.5, "using assertions")
programming style of 8.5.2 inline function
Keyword inline must be placed with the function definition body in order for the function to be inline, and it will have no effect but to place the inline in front of the function declaration. The following style of function Foo cannot be an inline function:
inline void Foo (int x, int y); Inline only with function declarations
void Foo (int x, int y)
{
...
}
And the following style of function foo becomes an inline function:
void Foo (int x, int y);
inline void Foo (int x, int y)//inline with the function definition body
{
...
}
So, inline is a "keyword for implementation", not a "keyword for declaration". Generally, users can read the declaration of a function, but do not see the definition of the function. Although the inline keyword is added to the declaration and definition of the inline function in most textbooks, I don't think inline should appear in the declaration of the function. This detail does not affect function, but it embodies a basic principle of high quality C++/C programming style: Declaration and definition can not be confused, users do not need, and should not know whether the function needs to inline.
The member functions defined in the class declaration will automatically become inline functions, such as
Class A
{
Public
void Foo (int x, int y) {...} Automatically become inline functions
}
To place the definition of a member function in a class declaration while writing is convenient, it is not a good programming style, the example should be changed to:
Header file
Class A
{
Public
void Foo (int x, int y);
}
Definition file
inline void A::foo (int x, int y)
{
...
}
8.5.3 with caution
Inline can improve the execution efficiency of functions, why not all functions are defined as inline functions?
If all of the functions are inline functions, is it also useful to have the keyword "inline"?
Inline is the cost of code expansion (replication), which simply eliminates the overhead of function calls, thus improving the execution efficiency of functions. If the time of executing the code in the function body is greater than the overhead of the function call, then there will be little efficiency gains. On the other hand, every call to an inline function replicates code, which increases the total code size of the program and consumes more memory space. The following conditions are not appropriate to use inline:
(1) If the code in the function body is longer, using inline will result in a higher cost of memory consumption.
(2) If there is a loop in the function body, the time to execute the code in the function body is greater than the cost of the function call.
The constructors and destructors of classes are easily misunderstood to be more efficient in using inline. Be aware that constructors and destructors may hide some behavior, such as "secretly" executing constructors and destructors for a base class or member object. So don't casually place constructors and destructor definitions in class declarations.
A good compiler automatically cancels the unworthy inline based on the definition of the function (this further demonstrates that inline should not appear in the declaration of a function).
8.6 Some experience
In C + + language, overloading, inline, default parameters, implicit conversion and other mechanisms show a lot of advantages, but these advantages are hidden behind a number of pitfalls. Just as people's diet, less food and gluttony are not desirable, should be right. We should look at the new mechanism of C + + dialectically and use them appropriately. Although this will allow us to program a lot of thought, less happy, but this is the art of programming.
9th chapter Constructors, destructors and assignment functions of class
constructors, destructors, and assignment functions are the most basic functions of each class. They are so common that they are easy to slumber, but these seemingly simple functions are as dangerous as sewers without top cover.
Each class has only one destructor and one assignment function, but it can have multiple constructors (including one copy constructor, others called normal constructors). For any class A, if you do not want to write the above function, the C + + compiler will automatically generate four default functions for a, such as
A (void); Default parameterless constructor
A (const a &a); Default copy constructor
~a (void); Default destructor
A & operate = (const a &a); The default assignment function
This makes people wonder, since the function can be automatically generated, why do programmers write?
The reasons are as follows:
(1) If you use the default parameterless constructor and the default destructor, you give up the opportunity to "initialize" and "purge", and the C + + inventor Stroustrup kindness in vain.
(2) "The default copy constructor" and "Default Assignment function" are implemented in the form of "bit copy" rather than "value copy", and if the class contains pointer variables, the two functions are doomed to error.
For those C + + programmers who haven't suffered enough, if he says it's easy to write constructors, destructors, and assignment functions, you can use your brain to show that his knowledge is superficial and that the level needs to be improved.
This chapter takes the design and the realization of the class string as an example, and elaborates the truth which is neglected by many textbooks. The string is structured as follows:
Class String
{
Public
String (const char *STR = NULL); Normal constructors
String (const string &other); Copy Constructors
~ String (void); destructor
String & operate = (const string &other); Assignment function
Private
Char *m_data; Used to save strings
};
======================================================================================================
At compile time, the compiler replaces the invocation expression of the inline function that appears in the program with the function body of the inline function. Obviously, this practice does not produce the problem of turning back, however, because the code in the function break is replaced in the program at compile time, it will increase the amount of the target program code, and then increase the space overhead, while the time distribution is not as big as the function call, it is the cost of increasing the target code in exchange for time saving.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.