Say I have a C macro-defined product version like this:
#define FOO_VERSION 1,0,0,1
And I want to print it at run-time:
#define STRING_VALUE(x) #x
int main()
{
std::cout << STRING_VALUE(FOO_VERSION) << std::endl;
}
This will output a string "FOO_VERSION", not "1,0,0,1". The macro argument 'FOO_VERSION' is not replaced. So I try it again like this:
#define STRING_VALUE(x) STRING_VALUE__(x)
#define STRING_VALUE__(x) #x
int main()
{
std::cout << STRING_VALUE(FOO_VERSION) << std::endl;
}
It works, in Visual C++ 2013.
This is a cross-platform application although there are only five lines of code. When I use clang to compile the code, a compile- time error appears: "too many arguments provided to function-like macro invocation". I guess the reason is the comma defined in 'FOO_VERSION'. So the third version:
#define STRING_VALUE(x) STRING_VALUE__(x)
#define STRING_VALUE__(a, b, c, d) #a "," #b "," #c "," #d
int main()
{
std::cout << STRING_VALUE(FOO_VERSION) << std::endl;
}
This code works in clang, but Visual C++ will output a warning: "not enough actual parameters for macro 'STRING_VALUE__'" at compile-time, of course the run-time output is not right.
My question: is this pre-processor behavior defined ? Can I have a universal version of STRING_VALUE macro ?
We can create two or more than two strings in macro, then simply write them one after another to convert them into a concatenated string. The syntax is like below: #define STR1 "str1" #define STR2 " str2" #define STR3 STR1 STR2 //it will concatenate str1 and str2. Input: Take two strings.
Macros just perform textual substitution. They can't return anything - they are not functions.
Macro Arguments (DEFINE-! ENDDEFINE command) The macro definition can include macro arguments, which can be assigned specific values in the macro call. There are two types of arguments: keyword and positional. Keyword arguments are assigned names in the macro definition; in the macro call, they are identified by name.
The double-number-sign or token-pasting operator (##), which is sometimes called the merging or combining operator, is used in both object-like and function-like macros. It permits separate tokens to be joined into a single token, and therefore, can't be the first or last token in the macro definition.
You can treat the argument as a single variadic macro:
#define FOO_VERSION 1,0,0,1
#define STRING_VALUE(...) STRING_VALUE__(__VA_ARGS__)
#define STRING_VALUE__(...) #__VA_ARGS__
This seems to work with gcc and Visual C++.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With