Advanced macro techniques for C language

Source: Internet
Author: User
Tags parse error

Special Symbol #, # #

(1) #

 When you put a # Before of argument in a preprocessor macro, the preprocessor turns that argument into a character array.

Using a # in front of a parameter in a macro, the preprocessor converts this argument to an array of characters 

Simplified understanding: #是 The meaning of "string", which appears in the macro definition # is to convert the following arguments into a string

#define ERROR_LOG (module)   "#module"\ n ")//NOTE 2 quotes

Error_log ("add"); Convert to fprintf (stderr, "Error:" Add "\ n");

Error_log (devied =0); Converted to fprintf (stderr, "error:devied=0\n");

(2) # #

"# #" is a way of separating connections, which are separated first and then forced to connect.

In the normal macro definition, the preprocessor generally interprets the space as the component segment flag, and the same is replaced for each segment and the previous comparison. However, the result is that there are some spaces between the replaced segments. If we don't want these spaces to appear, we can add some # #来替代空格.

1 #define TYPE1 (type,name)   type name_# #type # #_type2 #define TYPE2 (type,name)   type name# #_ # #type # #_type

TYPE1 (int, c); Converted to: int name_int_type; (Because # #号将后面分为 name_, type, _type three group, forced connection after substitution)
TYPE2 (int, d); convert to: int d_int_type; (because # #号将后面分为 name, _, type, _type four group, forced connection after substitution)

Macro definition do{}while (0)

There are several functions:

(1) An empty macro definition avoids warning:
#define FOO () do{}while (0)
  (2) There is a separate block, which can be used to define variables and make more complex implementations.
  (3) If a macro appears after a judgment statement, it is guaranteed to be implemented as a whole :
#define FOO (x) \
Action1 (); \
Action2 ();
In the following cases:
if (NULL = = Ppointer)
Foo ();
There will be situations where action1 and action2 will not be executed at the same time, which is clearly not the purpose of programming. If the do{} while (0) can be guaranteed as a whole.
(4) The 3rd situation above can also be achieved with a separate {}, but why must a do{}while (0), see the following code:
#define SWITCH (x, y) {int tmp; tmp= "x"; x=y;y=tmp;}
if (x>y)
switch (x, y);
else//error, parse error before else
Otheraction ();
    When you introduce a macro into your code, you will get an error by adding a semicolon. This makes it possible to avoid semicolon errors by enclosing the IF and else statements in {}.
Wrap it up with Do{....}while (0) and become a separate syntax unit so that it doesn't confuse the context. And because the vast majority of compilers are able to identify do{...} while (0) This useless loop is optimized, so using this method does not cause the program's performance to degrade.

-------------------------

Eliminate redundant semicolons-semicolon swallowing

Typically, to make a macro look like a normal C-language call on the surface, we usually add a semicolon to the macro, such as the following parameter macro:

My_macro (x);

But if the following is the case:

#define MY_MACRO (x) {/
/* Line 1 *//
/* Line 2 *//
/* Line 3 */}

//...

if (condition ())
My_macro (a);
Else
{...}

This will result in a compilation error due to the extra semicolon. To prevent this from occurring while maintaining My_macro (x), we need to define the macro as this form:

#define MY_MACRO (x) do {
/* Line 1 *//
/* Line 2 *//
/* Line 3 */} while (0)

This way, there is no problem as long as the semicolon is always used.

Duplication of Side Effects

The side effect here means that the macro can be evaluation (that is, the value) of its arguments when it is expanded, but if the macro argument is a function, it is possible to be called multiple times to achieve inconsistent results, even more serious errors. Like what:

#define MIN (x, y) > (Y)? (Y): (X))

//...

c = min (A,foo (b));

The Foo () function is then called two times. To solve this potential problem, we should write this macro as min (x, y):

#define MIN (x, y) ({/
typeof (x) X_ = (x);
typeof (Y) Y_ = (y);
(X_ < Y_)? X_: Y_; })

({...}) is to return the value of the last bar in several statements inside, and it also allows the variable to be declared internally (because it makes up a partial scope through curly braces).

(C language Keyword typeof introduction:

UsetypeofExample of a declaration

Here are two equivalent declarations for declaring variable aof type int .

typeof (int) A; /* Specifies variable a which is of the type int */typeof (' B ') A; /* the same. typeof argument is a expression consisting of                     character constant which has the type int * *

(

typeof (int) A;
typeof (a) B;

printf ("%d\n", sizeof (b));//4

)

The following example is used to declare pointers and arrays. In order to compare, the equivalent declaration without typeof is also given.

typeof (int *) p1, p2;/* declares, int pointers P1, p2 */ int *p1, *P2; typeof (int) * P3, p4;/* declares int pointer p3 and int P4 */ int * P3, P4; typeof (int []) A1, A2;/* declares, arrays of integers * * int a1[10], a2[10];

If typeof is used in an expression, the expression is not executed. Only the type of the expression is given. The following example declares a var variable of type int, because the expression foo () is of type int . The foo function is not called because the expression is not executed.

extern int foo (); typeof (Foo ()) var;
UsetypeofThe Claim restrictions

Note that the type name in thetypeof construct cannot contain a storage-class descriptor, such as extern or static. However, the inclusion of a type qualifier, such as const or volatile, is allowed. For example, the following code is invalid because it declares externin the typeof construct:

typeof (extern int) A;

The following code uses an external link to declare that identifier b is valid and represents an object of type int . The next declaration is also valid, which declares a char type pointer that uses the const Qualifier, indicating that the pointer p cannot be modified.

extern typeof (int) b;typeof (char * const) p = "a";
Using in a macro declarationtypeof

typeoF The primary application of the construct is in the macro definition. You can use the typeof keyword to refer to the type of the macro parameter .


Using typeof in a macro declaration
The main application of the TypeOf construct is in the macro definition. You can use the TypeOf keyword to refer to the type of the macro parameter. Therefore, it is possible to construct an object with the desired type without explicitly specifying the type name as a macro argument.
The following is a macro definition that swaps the values of two variables:
#define SWAP (A, b) {\
typeof (a) _t=a;\
A=b;\
b=_t;}
This macro can exchange variables of all basic data types (integers, characters, structures, etc.)

Applications in the Linux kernel:

/*linux-2.6.38.8/include/linux/kernel.h*/#defineMin (x, y) ({typeof(x) _min1 =(x); typeof(y) _min2 =(y); (void) (&_min1 = = &_min2); _min1< _min2?_min1: _min2;})#defineMax (x, y) ({typeof(x) _max1 =(x); typeof(y) _max2 =(y); (void) (&_max1 = = &_max2); _max1> _max2? _MAX1: _MAX2; })

The data types of x and Y are obtained by typeof, and then two temporary variables are defined, and the values of x and Y are assigned to both temporary variables, and finally the comparison is made.

In addition, the function of the (void) (&_min1 = = &_min2) statement in a macro definition is to warn that X and y cannot belong to different data types.

And container_of, look at the previous: http://www.cnblogs.com/youxin/p/3348227.html

Advanced macro techniques for C language

Related Article

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.