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