1 :__ file __,__ line __, macro expanded, Middle Layer Macro
_ File _ is the predefine macro of the compiler, indicating the absolute path of the file, but ASCII characters.
Suppose you want to convert _ file _ into a wide character.
Maybe you want
# DEFINE _ wfile _ L ##__ file __
Wchar_t pszfilepath [] =__ wfile __;
In this case, the compiler will prompt that "l1_file _" is an undeclared identifier.
Why?
If the parameter after # Is a macro, # will prevent the macro from being expanded, that is, it will only be replaced once. You need to add an intermediary to complete the replacement.
# DEFINE _ wfile3 _ (x) (L # X)
# DEFINE _ wfile2 _ (x) _ wfile3 _ (x)
# DEFINE _ wfile _ wfile2 _ (_ file __)
Wchar_t pszfilepath [] =__ wfile __;
When another macro function is called in the macro function definition, the pre-processor will expand all the available macros. In this way, you can.
Let's look at a confusing macro definition of an error:
# DEFINE _ wfile1 _ (x) (L # X)
# DEFINE _ wfile _ wfile1 _ (_ file __)
Wchar_t pszfilepath [] =__ wfile __;
In this case, the compiler will also report that l1_file _ is not defined, that is, l_file _ is not a string.
Let's take a step-by-step look at how the pre-processor works?
1. When the pre-processor reaches wchar_t pszfilepath [] =__ wfile __; it discovers the macro definition, and then runs the expand _ wfile1 _ (_ file __)
2. If _ file1 _ is a macro definition, expand it (L ##__ file1 __)
Why does the Preprocessor not expand _ file1 _? You may feel that you have added an intermediate step. But it does not actually exist. Let's just look at _ wfile1 _ (_ file _). If it doesn't close to other definitions, you will find that, this macro definition will never be expanded according to the previous rules, so the previous _ wfile _ does not play an intermediate replacement function.
To sum up, the first appearance from _ file _ must go through an intermediate macro. The macro layer in the middle refers to the macro that _ file _ must appear in the macro definition (on the left of the macro), and the macro definition (on the right of the macro definition) is also a macro. This macro is called the intermediate layer. This intermediate layer can expand _ file.
The following is an example of the wrong string macro definition.
# Define showlinenumw3 (x) (L # X)
# Define showlinenumw2 (x) showlinenumw3 (# X)
# Define showlinenumw (x) showlinenumw2 (X)
# DEFINE _ wline _ showlinenumw (_ line __)
# DEFINE _ wfile3 _ (x) (L # X)
# DEFINE _ wfile2 _ (x) _ wfile3 _ (x)
# DEFINE _ wfile _ wfile2 _ (_ file __)
# DEFINE _ n _ (_ wfile _ wline __)
Tchar szfilename [] =__ n __;
Note that L # X is enclosed in parentheses. Compiler prompt: the item is not calculated as a function that accepts one parameter.
Why? This is because when connecting multiple individual strings, it cannot be enclosed in brackets. Of course, one can be used separately.
For example:
Wchar_t sztemp [] = (L "nihao"); // The first type can be
Wchar_t sztemp [] = (L "nihao") (L "tahao"); // The second type cannot be used.
Wchar_t sztemp [] = l "nihao" L "woyehao"; // The third type is acceptable.
The preceding error example is equivalent to the second one after macro replacement, so the compiler reports an error. We need to change (L # X) to L # X to run correctly.
So the correct example is:
# Define showlinenumw3 (x) L # x
# Define showlinenumw2 (x) showlinenumw3 (# X)
# Define showlinenumw (x) showlinenumw2 (X)
# DEFINE _ wline _ showlinenumw (_ line __)
# DEFINE _ wfile3 _ (x) L # x
# DEFINE _ wfile2 _ (x) _ wfile3 _ (x)
# DEFINE _ wfile _ wfile2 _ (_ file __)
# DEFINE _ n _ (_ wfile _ wline __)
Tchar szfilename [] =__ n __;
2 :__ va_args __
_ Va_args _ seems to be a macro definition function added to the c99 standard, which may be used for constant parameter macros.
# Define my_printf (x,...) printf (x, ##__va_args __)
Where... indicates the variable parameter list, __va_args _ indicates the variable parameter list, where # is used to remove the comma before the variable parameter list. The compiler identifies # and removes the preceding comma.
If not ##:
# Define my_printf (x,...) printf (x, _ va_args __)
My_printf ("Hello World ");
After the grand scale:
Printf ("Hello World ",);
Such a compiler will complain about warnings or even fail to compile. Use. # Is also a connector.
Of course, sometimes we can directly:
# Define my_printf (...) printf (_ va_args __)
# Is Not required because there is no comma before.
I would like to summarize so much that I know. I will try again later.