How to comment lines automatically in release mode?
I need to have some lines of code "active" in debug mode only, and ignored in release mode. Is there a way to do something like this:
#include <iostream>
using namespace std;
#ifdef _TEST_
#define _cerr cerr
#else
#define _cerr // cerr
#endif
int main() {
_cerr << "TEST message" << endl;
}
So that when _TEST_
is not defined, some lines are commented, or removed from the code. I know that comments are processed before the rest, so this code is wrong. But how ca开发者_开发技巧n I get the behaviour I need without using #ifdefs explicitely?
You can use a macro for this:
#ifdef _TEST_
#define DEBUG_ONLY(x) x;
#else
#define DEBUG_ONLY(x)
#endif
int main() {
DEBUG_ONLY(cerr << "TEST message" << endl)
}
If what you are after is debug logging which is removed in release builds, you can do something like:
#ifdef _TEST_
#define LOG(x) (cerr << x << endl)
#else
#define LOG(x)
#endif
...
int main() {
LOG("TEST message");
}
Use this:
#ifdef _TEST_
#define DEBUG_TEST(x) x
#else
#define DEBUG_TEST(x)
#endif
int main() {
DEBUG_TEST(_cerr << "TEST message" << endl);
}
ifdefs are the way to go. How else would you know if the compiler is in release vs debug mode? When else besides during the preprocessing stage would that be communicated? At what other stage could you decide to remove/add code (besides during template generation). Hey maybe we can use template generation... but you still have to key off the ifdef somehow to control your template.
Maybe there's a really slick way to do this that I'm not thinking of, but everyone knows/uses ifdefs for this purpose. If you throw them a curveball its only going to drastically increase the human cost of maintaining your code.
Stick with ifdefs.
This here basically does what you are asking for:
#ifdef _TEST_
#define _cerr cerr
#else
#define _cerr if (1) {} else cerr
#endif
But don't be surprised if you for example get compiler warnings about ambiguous else
if you write something like this:
if (something)
_cerr << "Why?" << std::endl;
You should always be aware of the fact that this _cerr
is in fact a non-trivial macro.
Defining _cerr to nothing will fail the compilation. You could instead define a macro that you exclude while in release mode.
For example:
#ifdef _TEST_
#define LOG_ERROR(log) cerr << log << endl;
#else
#define LOG_ERROR(log)
#endif
Then in your code:
int main() {
LOG_ERROR("TEST message");
}
int main() {
#ifdef _TEST_
_cerr << "TEST message" << endl;
#endif
}
No. Absolutely, no.
Try a variation on this:
#ifdef _TEST_
ostream& _cerr = cerr;
#else
ostringstream _cerr;
#endif
(Basically you would want a stream which just discards its input.)
A nicer solution for the "no logging in release" is the following class:
class NullStream {
template<typename T> NullStream& operator<< const(T&) { }
};
Use:
#ifdef DEBUG
#define CERR std::cerr
#else
#define CERR NullStream()
#endif
Create your own NULL stream.
#include <iostream>
class NullStream {};
template<typename T>
NullStream& operator <<(NullStream& n,T const& data) {return n;}
NullStream& operator <<(NullStream& n,std::ostream& (*)(std::ostream&)) {return n;}
#ifdef _TEST_
#define myerr std::cerr
#else
NullStream myerrstream;
#define myerr myerrstream
#endif
int main()
{
myerr << "Hi" << std::endl;;
myerr << std::endl;;
}
精彩评论