One can remove all calls to printf() using #define printf. What if I have a lot of debug prints like std::cout << x << endl; ? How can I quickly switch off cout << statements in a single file using preprocessor?
As "unwind" already said, the quick solution is a do-nothing stream. There are better implementations though:
class NullStream {
public:
NullStream() { }
template<typename T> NullStream& operator<<(T const&) { return *this; }
};
You still have a slight issue with std::cout since that's a sequence of three tokens, and you really don't want to redefine std or cout individually. A simple solution is
#ifdef NDEBUG
#define COUT std::cout
#else
#define COUT NullStream()
#endif
COUT << "Hello, world" << std::endl;
As a general principle logging to stdout should be avoided - far better to log to a logfile, and then you can use standard configuration tools to change log levels, or turn it off altogether.
Just my $0.02.....
Substitute your debug output statements with something like this:
IFDBG(cout << result << endl);
Then you can define macros accordingly:
#ifdef DEBUG
# define IFDBG(x) x
#else
# define IFDBG(x)
#endif
Define this macro :
#ifdef DEBUG
#define MY_LOG std::cout
#else
#define MY_LOG if(false) std::cout
#endif
This macro advantage is in compiler optimization
If expressions placed inside those IFs are constant and determinable at the time of compilation, then you may be almost sure that the compiler has already removed them off the code for you...
https://stackoverflow.com/a/14657645/5052296
NullStream can be a good solution if you are looking for something quick that removes debug statements. However I would recommend creating your own class for debugging, that can be expanded as needed when more debug functionality is required:
class MyDebug
{
std::ostream & stream;
public:
MyDebug(std::ostream & s) : stream(s) {}
#ifdef NDEBUG
template<typename T>
MyDebug & operator<<(T& item)
{
stream << item;
return *this;
}
#else
template<typename T>
MyDebug & operator<<(T&)
{
return *this;
}
#endif
};
This is a simple setup that can do what you want initially, plus it has the added benefit of letting you add functionality such as debug levels etc..
Update:
Now since manipulators are implemented as functions, if you want to accept manipulators as well (endl) you can add:
MyDebug & operator<<(std::ostream & (*pf)(std::ostream&))
{
stream << pf;
return *this;
}
And for all manipulator types (So that you don't have to overload for all manipulator types):
template<typename R, typename P>
MyDebug & operator<<(R & (*pf)(P &))
{
stream << pf;
return *this;
}
Be careful with this last one, because that will also accept regular functions pointers.
You can probably do a preprocessor hack that defines a new stream-like class, with an instance named cerr, that just does nothing. If you're really lucky, the compiler will see that the function does nothing, and optimize the calls to operator<<() out.
Something like
class NullStream
{
public:
NullStream();
NullStream& operator<<(const std::string& text) { return *this; }
// And operators for other types, too
}
static NullStream cerr;
This is quite the hack though, it's (far) better to go through your source and add proper support for logging.
Defining a macro that replaces cout is not something you should upload to your VCS, but if you just do it temporarily during debugging, I think it serves its place. So you can just replace cout by ostream(0) like
#ifdef NDEBUG
#define cout ostream(0).flush()
#endif
This way, it works with both std::cout and plain cout, and ostream is available when including <iostream>. Writing into a ostream(0) is a no-op. The flush function call is done so that you get a non-const reference to it (so it also binds to non-member operator<< that's used for outputting std::string and others). As its type is ostream, it should behave exactly like cout.
Related
I need to create a debugging ofstream, which has the functionality as follows:
#define DEBUG true
int main() {
debug << "Hello World\n";
}
The output in the above case should be:Hello World
And for the following code-
#define DEBUG false
int main() {
debug << "Hello World\n";
}
The output should be empty.
Any suggestions how I should proceed.
With your usage I think debug needs to be macro as there is no other way to pick up the value of DEBUG. A simple definition would be this:
#define debug (debugstream << enable<DEBUG>)
extern std::ostream debugstream;
template <bool Enable>
std::ostream& enable(std::ostream& out) {
if (Enable) {
out.clear();
}
else {
out.setstate(std::ios_base::badbit);
}
return out;
}
std::ostream debugstream(std::cout.rdbuf()); // probably defined in a separate translation unit
The trick here is to enable/disable printing of the output using the stream's starte: no output is to be produced (by correctly written output operators) when the stream isn't in good state, I.e., if either std::ios_base::failbit or std::ios_base::badbit is set. This behaviour could be forced by setting/unsetting the stream buffer instead using rdbuf().
As I understand from your question, you wish for a separate debugging stream (in contrast to std::cout and std:cerr).
You could accomplish this by making a "null stream" that simply eats everything and does nothing.
If your compiler is clever enough then it should even remove most of this in the end.
class NullStream {};
template<typename T>
NullStream& operator<<(NullStream& s, T const &) { return s; }
NullStream& operator<<(NullStream& s, std::ostream&(std::ostream&)) { return s; }
Now based on your macro you decide whether to use the NullStream or an actual ostringstream.
#if DEBUG
std::ostringstream debug;
#else
NullStream debug;
#endif
Testing it like this:
debug << "Hello World\n";
debug << 12345 << "\n";
debug << "Test" << std::endl;
#if DEBUG
std::cout << "Debug:" << std::endl;
std::cout << debug.str() << std::endl;
#endif
If DEBUG is not 0 then that would yield:
Debug:
Hello World
12345
Test
Note that NullStream doesn't have any of std::ostream's functionality per se, so another solution could be to derive from std::ostream and discard any input it receives.
This question already has answers here:
C++ enable/disable debug messages of std::couts on the fly
(9 answers)
Closed 8 years ago.
Is there in C++ already some class which print to cout but can be off when some macro is not defined (for example DEBUG) ?
I can do like
#ifdef DEBUG
std::cout<<"some data"<<"new log<<"\n";
#endif
but is there already overridden operator<< so this be compressed on just one line
You can easily make your own:
namespace mystd
{
struct X {
template<typename T>
X& operator << (const T& x)
{
#ifdef DEBUG
std::cout << x;
#endif
return *this;
}
} cout;
}
and write
mystd::cout << " " << " ";
Simple answere: No, but you can implement this logic easily.
More advanced logging frameworks will actually define a bigger set of logging levels and decide to log based on the current level and the level of the message.
For an example you could take a look at the Poco framework: http://pocoproject.org/slides/110-Logging.pdf
They also offer an std::ostream wrapper around their logging framework
You could use std::ostream state flags to conditionally disable output. A corresponding use code look like this:
std::cout << log << "hello, ";
std::cout << "world\n";
The implementation which enables/disables output when using log could be something like the code below: log is actually constructing an objects which will disable the output if DEBUG is not defined when inserted into a stream by setting the stream flag std::ios_base::failbit. Its destructor will restore the stream state if the state got changed. Since a stream is used, you can also pass the stream object to a function and it will conditionally write output:
extern void f(std::ostream&);
f(std::cout << log);
Of course, the objects also work with other std::ostream objects, not just std::cout.
#ifndef SIMPLE_LOG
#define SIMPLE_LOG
#include <ostream>
class log_enabled
{
mutable std::ostream* stream;
mutable std::ios_base::iostate state;
bool logging;
public:
log_enabled(bool l)
: stream(0)
, state()
, logging(l) {
}
~log_enabled() {
if (stream) {
stream->clear(this->state);
}
}
std::ostream& setup(std::ostream& out) const {
if (!logging) {
this->stream = &out;
this->state = out.rdstate();
out.setstate(std::ios_base::failbit);
}
return out;
}
};
std::ostream& operator<< (std::ostream& out, log_enabled const& log) {
return log.setup(out);
}
# ifdef DEBUG
# define log log_enabled(true)
# else
# define log log_enabled(false)
# endif
#endif
I have stumbled upon an error for which I cannot grasp the reason.
I think it basically gets down to this error:
error: no matching function for call to ‘std::basic_ostream<char>::operator<<(const std::basic_string<char>&)’
I looked into specification on www.cplusplus.com and indeed it says there is no definition for std::ostream::operator<< with std::string as an argument.
My question is, what happens when one writes std_ostream_instance << std_fancy_string;. I believe it is one of the most common invocations ( e.g. std::out << std::string("Hello world!") ) next to const char*.
The error originates from these lines:
template<typename T>
void Log::_log(const T& msg)
{ _sink->operator<<( msg ); }
_sink is defied as std::ostream*
There are some wrapping functions around but it breaks here.
I think I could work around by writing
template<>
void Log::_log<std::string>(const std::string& msg) {
_sink->operator<<( msg.c_str() );
}
since there is ostream& operator<< (ostream& out, const unsigned char* s ); defined by default.
I just see no reason why it is not guessed automatically since it clearly works in simple use like cout << any_std_string.
Not sure if this is relevant but I want to be able to pass down through my log functions anything than can be handled by std::ostream. I used explicit non-templated declarations but decided to move to template for log(const T& anything_to_log) to refacator it. It seemed plain stupid to have 5+ overloads. I get the error when I try compiling something like Log::log( std::string("test case") ).
It looks like something stupid-simple but I cannot get it on my own. Tried to google and search stack to no avail.
With regards, luk32.
PS. I checked the work-around and it works. Why it's not implicitly done ?
operator << overloads are not members of ostream. They are freestanding functions, for example
ostream& operator << ( ostream& out, const basic_string<T>& bs );
Try
template<typename T>
void Log::_log(const T& msg)
{ *_sink << msg; }
The std::string version is not a member function, so can't be called as a member of _sink. Try it this way to pick up both member and non-member versions (in fact it is unlikely you will need the member versions at all anyway):
#include <iostream>
#include <string>
int main()
{
std::ostream * os = &std::cout;
std::string s = "Hello\n";
// This will not work
// os->operator<<(s);
(*os) << s;
return 0;
}
Or better yet would be to store _sink as a reference, and output exactly as you normally would to cout.
EDIT: The code marked as "not working" was actually working. It was because of a syntax problems in my tests, not detected by the compiler. So the question is already solved, thank you.
C++ is not a language I use everyday, so it is possible that the solution is trivial.
About the context first. I use C++ to develop on a microcontroller (Arduino-based, AVR microcontroller), so I do not use the STL, printf-like functions, new/malloc should be avoided and C++ <string> too.
I have an object called Serial similar to the C++ cout iostream, to communicate with the microcontroller with a serial interface. I have overloaded the "<<" operator of the class from which Serial is an instance so I can do something like that:
Serial << "debug " << "value is " << 3 << endl;
// Whithout the << operator it would be:
Serial.print("debug ");
Serial.print("value is ");
Serial.println(3);
I would like to create a function (or a macro) that enables this kind of line only if debugging is enabled, and which automatically add the "debug" string and append the "endl" value at the end.
So something like that (warning, code does not work because "data" cannot expand as a whole C++ instruction):
#ifdef DEBUG
#define PRINT_DEBUG(data) do {Serial << "debug " << data << endl;} while(0)
#else
#define PRINT_DEBUG(data) do {} while(0)
#endif
// This code works
PRINT_DEBUG("hello world");
// This code does not work
int value1 = 3;
char * value2 = "this is a string";
PRINT_DEBUG("sensor1 value:" << value1 << " other sensor value " << value2);
This kind of function/macro would allow me to easily output strings on my serial interface with a specific "string protocol" without having to repeat the "debug" string at the start. It would also allow me to easily disable the print of debug message by not setting the DEBUG macro. I also have only one "#ifdef DEBUG" instead of several ones in my code.
I managed to do something like that with variadic arguments, but I hate this solution because it is dangerous to use (I do not want to specify the number of arguments), and I cannot mix different type of data:
void __rawSend(char * args, ...) {
Serial.print(args);
va_list paramList;
va_start (paramList, args);
while(true) {
char * next = va_arg(paramList, char*);
if (next == NULL) {
break;
}
Serial.print(" ");
Serial.print(next);
}
Serial.println();
va_end(paramList);
}
#ifdef DEBUG
#define printDebug(...) do {__rawSend(OUTPUT_DEBUG, __VA_ARGS__, NULL);} while(0)
#else
#define printDebug(...) do {} while(0)
#endif
int intValue = 1;
char * stringValue = "data";
// This works
printDebug("hello",stringValue);
// This does not works
printDebug("data is", intValue);
How can I do that? Is it possible with macros (while avoiding variadic arguments and mixing different kind of types)? Is there a better solution?
Sorry all, the code marked as "not working" does actually work. It was because of a syntax problems in my tests, not detected by the compiler.
Anyway, my solution can benefit other people working with Arduino, as I have seen solutions using printf or trying to recreate printf.
I used the "<<" operator coming from http://arduiniana.org/libraries/streaming/
I tend to avoid macros for this sort of things and use classes and static polymoprhism instead :
// Define different types providing a stream interface
struct DebugStream
{
template <typename T>
std::ostream & operator<< (const T & x) const {
return Serial << "debug " << x;
}
// This one is for stream manipulators
std::ostream & operator<< (std::ostream& (*x) (std::ostream&)) const {
return Serial << "debug " << x;
}
};
// This type also provides a stream-like interface but does nothing
struct NoStream
{
template <class T>
const NoStream & operator<< (const T & x) const {
return *this;
}
const NoStream & operator<< (std::ostream& (*x) (std::ostream&)) const {
return *this;
}
};
// Instanciate a debug object having one of the previously defined types
//
// Make sure to declare debug in a common .hxx file included everywhere else
// but to define it only once in a .cxx file.
#ifdef DEBUG
DebugStream debug;
#else
NoStream debug;
#endif
// Use it like you would use the Serial iostream
debug << "value is " << 3 << std::endl;
Since everything is inlined and exact types are known at compile-time, the compiler can optimize out all unnecessary operations on NoStream instances.
If I understand your problems correctly...
Looks to me like you need to overload operator<< for all types you're going to send to the debug interface.
The var args macro has to have a way to deduce the types of its arguments. The way you have it implemented it's expecting all C type strings. You'd be better off with printf or a library like fastformat.
If your operator<< is not returning a reference to the class that allows operator<< to be chained, you'll get errors like "I have the following error for the line "DEBUG("hello" << " " << "world");" : invalid operands of types 'const char [6]' and 'const char [2]' to binary 'operator<<' ". I do not believe DEBUG("hello" << " " << "world"); can be made to work. DEBUG( "hello", "world"); might work.
I'm trying to implement my own qDebug() style debug-output stream, this is basically what I have so far:
struct debug
{
#if defined(DEBUG)
template<typename T>
std::ostream& operator<<(T const& a) const
{
std::cout << a;
return std::cout;
}
#else
template<typename T>
debug const& operator<<(T const&) const
{
return *this;
}
/* must handle manipulators (endl) separately:
* manipulators are functions that take a stream& as argument and return a
* stream&
*/
debug const& operator<<(std::ostream& (*manip)(std::ostream&)) const
{
// do nothing with the manipulator
return *this;
}
#endif
};
Typical usage:
debug() << "stuff" << "more stuff" << std::endl;
But I'd like not to have to add std::endl;
My question is basically, how can I tell when the return type of operator<< isn't going to be used by another operator<< (and so append endl)?
The only way I can think of to achieve anything like this would be to create a list of things to print with associated with each temporary object created by qDebug(), then to print everything, along with trailing newline (and I could do clever things like inserting spaces) in ~debug(), but obviously this is not ideal since I don't have a guarantee that the temporary object is going to be destroyed until the end of the scope (or do I?).
Something like this will do:
struct debug {
debug() {
}
~debug() {
std::cerr << m_SS.str() << std::endl;
}
public:
// accepts just about anything
template<class T>
debug &operator<<(const T &x) {
m_SS << x;
return *this;
}
private:
std::ostringstream m_SS;
};
Which should let you do things like this:
debug() << "hello world";
I've used a pattern like this combined with a lock to provide a stream like logging system which can guarantee that log entries are written atomically.
NOTE: untested code, but should work :-)
Qt uses a method similar to #Evan. See a version of qdebug.h for the implementation details, but they stream everything to an underlying text stream, and then flush the stream and an end-line on destruction of the temporary QDebug object returned by qDebug().
When you write that this is the typical usage:
debug() << "stuff" << "more stuff" << std::endl;
are you definitely planning to construct a debug object each time you use it? If so, you should be able to get the behavior you want by having the debug destructor add the newline:
~debug()
{
*this << std::endl;
... the rest of your destructor ...
}
That does mean you cannot do something like this:
// this won't output "line1" and "line2" on separate lines
debug d;
d << "line1";
d << "line2";
The stream insertion (<<) and extraction (>>) are supposed to be non-members.
My question is basically, how can I
tell when the return type of
operator<< isn't going to be used by
another operator<< (and so append
endl)?
You cannot. Create a member function to specially append this or append an endl once those chained calls are done with. Document your class well so that the clients know how to use it. That's your best bet.