Running the following code
#include <iostream>
#define FOO
#define BAR defined(FOO)
int main() {
#if BAR
std::cout << "BAR enabled!" << std::endl;
#else
std::cout << "BAR disabled!" << std::endl;
#endif
return 0;
}
in Visual Studio displays Bar disabled!, while running the same code in gcc or clang displays Bar enabled!.
Is this a bug in the Microsoft compiler? What is correct according to the standard?
This is undefined behavior according to the standard.
[cpp.cond], emphasis mine
Prior to evaluation, macro invocations in the list of preprocessing tokens that will become the controlling constant expression are replaced (except for those macro names modified by the defined unary operator), just as in normal text. If the token defined is generated as a result of this replacement process or use of the defined unary operator does not match one of the two specified forms prior to macro replacement, the behavior is undefined.
Related
I am using ## (Token-Pasting Operator) to form a function call.
According to my understanding, a simple example may look like this.
#include <iostream>
#define CALL(x) Func_##x##()
void Func_foo() { std::cout << "Hi from foo()." << std::endl; }
int main() {
std::cout << "Hello World!" << std::endl;
CALL(foo);
return 0;
}
I compiled this code with g++ -std=c++14 -O3 test.cc. The G++ version is 7.3.1.
It returns the following error.
error: pasting "Func_foo" and "(" does not give a valid preprocessing token
If I change the macro to #define CALL(x) Func_##x() (delete the second ##), the error will be solved.
Why the second ## is redundant? The ## connects strings and substitutes with macro arguments if possible. For example, I change the function name to Func_foo1(), then the macro should be #define CALL(x) Func_##x##1(). This works as my expected.
I am a little confused about the macro definition #define CALL(x) Func_##x().
A token is the smallest element of a C++ program that is meaningful to the compiler.
The ## Token-pasting operator does not concatenate arbitrary printable characters. It concatenates two tokens into one token.
Why the second ## is redundant?
Because concatenating Func_foo and () does not produce a single token.
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 ?
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++.
Is this code snippet portable?
definition:
#define log(...) std::cout << __FILE__ << "[" << __LINE__ << "]:" \
<< string_format(__VA_ARGS__) \
<< std::endl << std::flush
usage:
log("i = %d", i);
and string_format is sprintf that outputs a std::string taken from https://stackoverflow.com/a/8098080/624074 It works with my gcc 4.6.3 here but I don't want to have compilation issues later with other compilers.
Yes, the macro __VA_ARGS__ is part of standard C++:
C++11 ยง16.3.1 Argument substitution
An identifier __VA_ARGS__that occurs in the replacement list shall be treated as if it were a parameter, and the variable arguments shall form the preprocessing tokens used to replace it.
It's pretty portable, for the most part. It's part of the C++11 language standard (as well as C99), so most modern compilers support it. You might run into problems with older compilers that only support C++03.
Given the following code:
1. #include <iostream>
2. #define CALL_FUNC(f) f();
3.
4. int main()
5. {
6. CALL_FUNC([](){
7. std::cout << "I'm on line " << __LINE__ << std::endl;
8. });
9. return 0;
10. }
When I compile this in Visual Studio 2012 and g++ 4.7.3, I get the output "I'm on line 8".
When I compile this in clang, I get the output "I'm on line 7", which is what I expected.
Does anyone know which of these is the correct behavior? Is there a way to get the desired behavior in VS and g++ while still having a CALL_FUNC macro?
The standard does not specify the interaction between macro expansion and the __LINE__ predefined macro. In particular a macro invocation that spans multiple lines and contains a __LINE__ token exhibits different behaviours on different preprocessors. When part of a macro argument that is expanded, some will give it the line number of the enclosing macro head name (6), some the closing parenthesis (8) and some the __LINE__ token line (7). It depends on the algorithm used, and there are several that are valid and standard-conformant.
This can be demonstrated as follows:
#define F(x) x
F(
__LINE__
)
Some preprocessors will output 2, some 3 and some 4.
A quick test seems to show that if you move the }); up a line it works:
std::cout << "I'm on line " << __LINE__ << std::endl;});
gcc and msvc seem to think it is on the next line because of the }); on the next line.
(Also, you have an extra semi-colon BTW).
__FILE__ and __LINE__ are well known. There is a __func__ since C99.
#include <iostream>
struct Foo {
void Do(){ std::cout << __func__ << std::endl; }
};
int main()
{
std::cout << __func__ << std::endl;
Foo foo; foo.Do();
return 0;
}
will output
main
Do
Is there any macro / keyword that would output method name like Foo::Do?
Boost has a special utility macro called BOOST_CURRENT_FUNCTION that hides the differences between the compiler implementations.
Following it's implementation we see that there are several macros depending on compiler:
__PRETTY_FUNCTION__ -- GCC, MetroWerks, Digital Mars, ICC, MinGW
__FUNCSIG__ -- MSVC
__FUNCTION__ -- Intel and IBM
__FUNC__ -- Borland
__func__ -- ANSI C99
On GCC you can use __FUNCTION__ and
__PRETTY_FUNCTION__.
On MSVC you can use __FUNCSIG__ and __FUNCTION__.
There's no such macro in standard C++, and that includes the draft C++0x standard I looked at. It would complicate compilation, since parsing (necessary to determine what a function is) comes after preprocessing, and I suspect that's why there's nothing in the standard.
The __func__ you're using is nonstandard, although it apparently works on your compiler.
Not in Standard C++ (and __func__ is not part of C++). Your implementation may have such a feature though - which compiler are you using?
See "Predefined Macros (C/C++)" for a complete list supported by MS Visual Studio.
This might be useful:
http://gcc.gnu.org/onlinedocs/gcc/Function-Names.html
#include"stdio.h"
#include"stdlib.h"
int main()
{
printf("line number is %d .. func name is %s, file name is %s",__LINE__,__PRETTY_FUNCTION__,__FILE__);
return 0;
}
This is how to print line number, function name and file name in gcc.