Macro definition conflict

1. Max min conflict in stl

Macros are not namespaced, they are done in the precompile phase , and namespaces are in the compilation phase

(1) The following code will compile error

namespace TT

{

#define MAX(a,b)            (((a) > (b)) ? (a) : (b))

}

namespace Test

{

typedef void (*Func)();

int MAX(int a, Func func)

//int MAX(int a, int b)

{

return 0;

}

}

(1) The content of the test.cpp file is as follows, the compilation cannot pass

#define max(a,b)            (((a) > (b)) ? (a) : (b))

namespace TEST{

inline int max(int a, int b)

{

return            (((a) > (b)) ? (a) : (b));

}

}

(2) The content of the test.cpp file as follows, the compilation will report an error, because the algorithm contains max(const _Tp&, const _Tp&);

#include <list>

#define max(a,b)            (((a) > (b)) ? (a) : (b))

#include <algorithm>

(3) But the strange thing is that the following content can be compiled and passed

#define max(a,b)            (((a) > (b)) ? (a) : (b))

#include <algorithm>

(4) About the reasons for (2) and (3). By tracing the stl code, we found the following

  • The header file exists in the stl source: c++/config.h in /usr/include/c++/4.8/x86_64-w64-mingw32/bits/ (64-bit) or /usr/include/c++/4.8/i686-w64-mingw32/ bits/ (32-bit) . This header file contains the following sections

#ifndef _GLIBCXX_CXX_CONFIG_H

#define _GLIBCXX_CXX_CONFIG_H 1

......

// For example, <windows.h> is known to #define min and max as macros...

#undef min

#undef max

......

#endif // _GLIBCXX_CXX_CONFIG_H

  • Generally, header files such as <list> or <algorithm> contain the c++config.h header file.

  • When precompiling, corresponding to (2) when #include<list>, it will be included in the c++ config.h header file, #undef min and #undef max are introduced, and then #define max leads to the macro definition of max, and finally When #include<algorithm>, although it also includes the c++config.h header file, because c++config.h has guard protection, that is, the above _GLIBCXX_CXX_CONFIG_H, it has been introduced when #include<list> Included, so when #include<algorithm>, this header file will not be included, so #undef max will not be introduced again. Eventually, std::max() in #include<algorithm> will be defined. The macro is replaced, causing subsequent compilations to fail

  • Tracking method, track each header file step by step, add comments, and then precompile to see the results g++ -E test.cpp -o test.i

#include <list>

#define max(a, b) ((a) > (b) ? (a) : (b))

//#include "c++config.h"

//void max(int a, int b);

//{}

//#include <algorithm>

//#include <vector>

#include </usr/include/c++/4.8/bits/algorithmfwd.h>

//void max(int a, int b, int c);

//{}

intmain()

{

return 0;

}

2. Use of # and ##

     (1) # is to perform string operations on the following macro parameters, that is, to enclose the following parameters in double quotation marks.

## is for connection.

for example:

#define PRINT(NAME) printf("token"#NAME"=%d\n", token##NAME)

Use when calling: PRINT(9);

The macro expansion is: printf("token"#9"=%d\n",token##9);

#9 is "9", token##9 is: token9

The whole is: printf("token""9""=%d\n",token9);

The token9 was defined as 9 before, so the output token9=9;

(2) Symbols after ## are not allowed under gcc, such as +-*/.->, otherwise the compilation will fail

  However, two tokens that don’t together form a valid token cannot be pasted together. For example, you cannot concatenate x with + in either order. If you try, the preprocessor issues a warning and emits the two tokens. Whether it puts white space between the tokens is undefined

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324896085&siteId=291194637