original text :C Advanced application of language macro

About # and ## stay C In the macro of language ,# Its function is to string the macro parameters after it (Stringfication), To put it simply, I'm referring to Macro variable After replacement, add a double quotation mark on the left and right . For example, the macro in the following code :

#define WARN_IF(EXP)
do{
if (EXP)
fprintf(stderr, "Warning: " #EXP ");
} while()

Then the replacement process shown below will appear in actual use :

WARN_IF (divider == ); Be replaced by 
do {
if (divider == )
fprintf(stderr, "Warning" "divider == 0" "");
} while();

So every time divider( Divisor ) by 0 A prompt message will be output on the standard error stream .

and ## It's called a connector (concatenator), Used to put two Token Connect to a Token. Note that the connected object here is Token Just go , and not always Is a macro variable . For example, you need to make an array of structures composed of menu item, command name and function pointer , And we want to have an intuitive relationship between the function name and the menu command name 、 The relationship between names . So the following code is very practical :

struct command {
char * name;
void (*function) (void);
};
#define COMMAND(NAME) {
NAME, NAME ## _command
}

// Then you can easily initialize a with some predefined commands command An array of structures :

struct command commands[] = { COMMAND(quit), COMMAND(help), ... }

COMMAND The macro acts as a code generator here , This can reduce code density to a certain extent , Indirectly, it can also reduce the mistakes caused by inattention . We can still n individual ## Symbolic connection n+1 individual Token, This feature is also # What symbols don't have . such as :

#define LINK_MULTIPLE(a,b,c,d) a##_##b##_##c##_##d
typedef struct _record_type LINK_MULTIPLE
(name,company,position,salary);
// Here the statement will expand to :
// typedef struct _record_type name_company_position_salary

About ... Use

... stay C The macro is called Variadic Macro, That is, variable parameter macro . such as :

#define myprintf(templt,...) fprintf(stderr,templt,__VA_ARGS__)
// perhaps
#define myprintf(templt,args...) fprintf(stderr,templt,args)

In the first macro, there is no variable parameter named , We use the default macro __VA_ARGS__ To replace it . In the second macro , We explicitly name the variable parameter as args, Then we can use args It's a change of reference . Same as C Linguistic stdcall equally , The variable parameter must appear as the most important item in the parameter list . In the macro above, we can only provide the first parameter templt when ,C Standards Please, we have to write :

myprintf(templt,);

In the form of . The replacement process is :

myprintf("Error!",);
Replace with :
fprintf(stderr,"Error!",);

This is a grammatical error , Cannot compile properly . There are generally two solutions to this problem . First ,GNU CPP The solution provided allows the macro call above to be written as :

myprintf(templt);

And it will be replaced by :

fprintf(stderr,"Error!",);

Obviously , There will still be compilation errors ( In some cases other than this, compilation errors will not occur ). Except in this way ,c99 and GNU CPP The following macro definition methods are supported :

#define myprintf(templt, ...) fprintf(stderr,templt, ##__VAR_ARGS__)

At this time ,## The purpose of this connection symbol is to __VAR_ARGS__ When it's empty , Remove the previous comma . Then the translation process is as follows :

myprintf(templt);
Converted to :
fprintf(stderr,templt);

So if templt legal , There will be no compilation errors .

Wrong nesting -Misnesting

The definition of a macro doesn't have to be complete 、 Paired brackets , But to avoid mistakes and improve readability , It's better to avoid using it like this .

Problems caused by operator priority -Operator Precedence Problem

Because the macro is just a simple replacement , If the macro parameter is a composite structure , After replacement, the priority of operators among parameters may be higher than the priority of operators among parts within a single parameter , If we don't use brackets to protect macro parameters , There may be unexpected situations . such as :

#define ceil_div(x, y) (x + y - 1) / y

that

a = ceil_div( b & c, sizeof(int) );

Will be converted into :

a = ( b & c + sizeof(int) - 1) / sizeof(int); 
// because +/- Has a higher priority than & The priority of the , So the above equation is equivalent to :
a = ( b & (c + sizeof(int) - 1)) / sizeof(int);

This is obviously not the original intention of the caller . To avoid that , More parentheses should be written :

#define ceil_div(x, y) (((x) + (y) - 1) / (y))

Eliminate redundant semicolons -Semicolon Swallowing

Usually , To make a function like macro look like a normal C Language calls are the same , Usually we put a semicolon after the macro , For example, the following macro with parameters :

MY_MACRO(x);

But if it's the following :

#define MY_MACRO(x) { 
/* line 1 */
/* line 2 */
/* line 3 */
}
//...
if (condition()) MY_MACRO(a); else {...}

This will cause compilation errors due to the extra semicolon . To avoid this and keep MY_MACRO(x); This way of writing , We need to define a macro in this form :

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

So just make sure you always use semicolons , There won't be any problems .

Duplication of Side Effects

there Side Effect When a macro is expanded, its parameters may be changed many times Evaluation( That is to say, the value of the value ), But if the macro argument is a function , Then it is possible to be called many times to achieve inconsistent results , Even more serious mistakes will happen . such as :

#define min(X,Y) ((X) > (Y) ? (Y) : (X))
//...
c = min(a,foo(b));

At this time foo() The function is called twice . To solve this potential problem , We should write like this min(X,Y) This macro :

#define min(X,Y) ({ typeof (X) x_ = (X); typeof (Y) y_ = (Y); (x_ < y_) ? x_ : y_; })

({...}) The function of is to return the value of the last one of the internal statements , It also allows variables to be declared internally ( Because it makes up a part with braces Scope)

C Language macro advanced application of more related articles

  1. Visual Studio Advanced usage of macro

    Because self Visual Studio 2012 Start , Microsoft has removed support for macros , Therefore, this article only applies to Visual Studio 2010 Or earlier versions of VS. In the last one , I've shown you how to make ...

  2. [ turn ] Advanced use of macro --##,__VA_ARGS__, __FILE__, __FUNCTION__ etc.

    [ turn ] Advanced use of macro --##,__VA_ARGS__, __FILE__, __FUNCTION__ etc. http://blog.csdn.net/yiya1989/article/details/784 ...

  3. 14-C Language macro

    Catalog : One . Macro definition Two .#x,##x Use and pre define macros 3、 ... and . Advanced use of macro ( Conditional compilation ) Back to the top One . Macro definition 1 Macro is one of the common preprocessing functions , It's macro replacement before compilation , That is, replace the macro name with the defined macro body . 2 advantage : can ...

  4. C Language macro /macor/#define/

    C Language macro /macor/#define Advanced skills 1. During debugging , Need to print /PRINT, Can pass define Customize . for example , My most common DEBUG_PRINT() #define DEBU ...

  5. C Language grammar notes – Advanced usage Pointer array The pointer of the pointer Two dimensional array pointer Structure pointer Linked list | IT house .com

    original text :C Language grammar notes – Advanced usage Pointer array The pointer of the pointer Two dimensional array pointer Structure pointer Linked list | IT house .com C Language grammar notes – Advanced usage Pointer array The pointer of the pointer Two dimensional array pointer Structure pointer Linked list | I ...

  6. 2018 On C Language programming ( senior ) Homework - A preliminary plan

    C Language programming ( senior )36 Class hours , Once a week 4 Class hours , common 9 Zhou . Main learning indicators . Structure and document are three parts . The assignment plan of the whole course is as follows : PTA And a guide to using blogs If you use it for the first time PTA And blog , Please make sure that PTA A brief introduction to the use of and how the teacher works in ...

  7. C Advanced operation of language pointer

    C Advanced operation of language pointer The pointer   The pointer In my last blog, I introduced C The most basic operation of language pointer , So I'll talk about it in this blog C Some operations of language pointer . The pointer to the pointer The name sounds a bit awkward at first , It's more difficult to hear it again . Let's see ...

  8. C Language macro definition

    C Language macro definition 1. Examples are as follows : #define PRINT_STR(s) printf("%s",s.c_str()) string str = "abcd"; ...

  9. take C Language macro defines the conversion of numeric values into strings !

    take C The language macro definition is converted to a string ! Excerpt from :https://blog.csdn.net/happen23/article/details/50602667 2016 year 01 month 28 Japan 19:15:47  Six nineties ...

Random recommendation

  1. mysql5.6 Source code installation

    1. Introduction to the environment : package :mysql-5.6.24.tar.gz platform :centos6.5 2. install cmake Compiler tools and dependency packages : yum install cmake -y yum install ncurs ...

  2. SQL Server Yes Xml Field operation

    T-Sql operation Xml data One . Preface SQL Server 2005 The introduction of a method called XML The native data type of . Users can create tables like this , It has one or more other than the off series XML Column of type : Besides , Variables and ...

  3. hdu 1063(java Write high precision )

    Topic link :http://acm.hdu.edu.cn/showproblem.php?pid=1063 Ideas : I just learned java, And then I can't wait to try java The benefits of big numbers , ha-ha , It's really convenient ! i ...

  4. Linux Next MySQL No remote access

    Recently Linux It's loaded with MySQL database , But remote connection MySQL I always report erro 2003: Can't connect to MySQL server on '211.87.***.***' (1 ...

  5. apache-ab Concurrent load stress testing ( turn )

    ab Command principle  Apache Of ab Commands simulate multithreaded concurrent requests , Test server load stress , You can also test nginx.lighthttp.IIS Others, such as Web Server pressure . ab Commands require very little of the computer issuing the load , It doesn't take much ...

  6. UI Learning notes --- The fourth day

    Event handling Summary of events UIEvent: event , Is an object captured by hardware that represents the user operating the device There are three categories : Touch event \   Shaking Events \ Remote control events Touch event : Will contain 1 Touch points to touch points To achieve touch UIView Support for touch events ...

  7. Tab Tab switch

    js And tab Tab switching effect       Now? web Website , A lot of it needs to be used tab Tab . Example :         $(document).ready(function(){               va ...

  8. python Basic course No 3 Chapter —— character string

    1. String formatting String formatting operators %+ Conversion logo + Minimum field width + Point followed by precision value + Conversion type String Modules provide another way to format from string import Template s=Templa ...

  9. Flow Problem( Maximum flow )

    Flow Problem Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Tot ...

  10. 2019.04.09 Online retailers 19 analysis carmanage.py

    post(self,request) This request do There's recursion , He called that getcarmanager Function returns another function . This other function is responsible for creating the insert data def __init__(sel ...