Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to switch on/off std:cerr (or equivalent)?

Without using a full-blown logging library (or IF statements) - is there a way in C++ to sometimes print out messages to the console and sometimes not?

I am using std::cerr, is there a way to control when this outputs or not?

Ideally I could have:

std::cerr << "Constructor called" << endl;

and have a way to enable/disable this line of code?

like image 697
user997112 Avatar asked Dec 21 '25 05:12

user997112


2 Answers

I am not sure what you mean by "without if", but you can write code without using the if yourself. A macro can check a flag for you.

#define CERR if (cerr_disabled) {} else std::cerr
bool cerr_disabled = false;

Then, in your code:

CERR << "error message" << std::endl;

If cerr_disabled is true, then nothing is printed.

The advantage of this macro approach is that none of the print arguments get evaluated if the err logging is disabled. For instance, if you needed to call a function to create a more complicated log string:

std::string fancy_log_message () {
    //...
}

CERR << fancy_log_message();

If cerr_disabled is true, fancy_log_message() is not called. This is something that can't be achieved by just suppressing the stream object itself.

like image 88
jxh Avatar answered Dec 23 '25 18:12

jxh


The simple approach is to set/clear std::ios_base::failbit on the stream: while std::ios_base::failbit is set, the streams won't do any work [unless the output operators are written incorrectly]:

std::cerr.setstate(std::ios_base::failbit);
std::cerr << "this won't show\n";
std::cerr.clear();
std::cerr << "this will show!\n";

To make these operations easier to use you can create manipulators, e.g.:

std::ostream& stream_on(std::ostream& out) {
    out.clear();
    return out;
}
std::ostream& stream_off(std::ostream& out) {
    out.setstate(std::ios_base::failbit);
    return out;
}

std::cerr << stream_off << "not printed\n" << stream_on << "printed\n";

If you really want to disable the stream even if the output operators are badly implemented, you can save the current rdbuf() (e.g., in a suitable std::ostream::pword()) and set the stream buffer to nullptr:

static int stream_off_index() { static int rc = std::ios_base::xalloc(); return rc; }
std::ostream& stream_on(std::ostream& out) {
    out.pword(stream_off_index) = out.rdbuf(nullptr);
    return out;
}
std::ostream& stream_off(std::ostream& out) {
    if (!out.rdbuf()) {
        out.rdbuf(out.pword(stream_off_index);
    }
    return out;
}
like image 43
Dietmar Kühl Avatar answered Dec 23 '25 18:12

Dietmar Kühl