Cryptography Man
Cryptography Man

Reputation: 209

Somehow tell compiler to "Do not process line of code"

I'm trying to create a macro for debug logging purposes. Here is an extra simplified version:

#if defined _DEBUG
#define LOG std::cout
#else
#define LOG IGNORETHISLINEOFCODE
#endif

/* ... */

LOG << "Here's some debug code";

I've been thinking of the ways I can tell the compiler to ignore this line of code that starts with "LOG". I'm personally not looking for alternative ways, such as #define LOG( ... ) (void)0. Here's what I've tried:

Any ideas? Like I said earlier, I don't want any alternatives, such as surrounding all the log code with #if defined _DEBUG

Upvotes: 2

Views: 219

Answers (5)

Cryptography Man
Cryptography Man

Reputation: 209

#if defined _DEBUG
#define LOG std::cout
#else
#define LOG /##/
#endif

This works as well. It's the answer to the original question, so I'll mark it as such, but just know that this does not support multiline operations.

I suppose you could do something like the following for multiline operations. I don't know how well it'd work.

#if defined _DEBUG
#define LOG( in ) std::cout << in
#else
#define LOG( in ) /##/
#endif

Upvotes: 0

Serge
Serge

Reputation: 12344

another possibility based on the compiler optimization abilities:

#define LOG if (DEBUG) std::cout

now you can use

#define DEBUG false
LOG << "hello " << " world 1" << endl;

you should be able to use const bool DEBUG = false as well.

Upvotes: 2

Useless
Useless

Reputation: 67713

Your question and constraint ("I don't want any alternatives") are weirdly specific.

I've been thinking of the ways I can tell the compiler to ignore this line of code that starts with "LOG"

Don't do that, it'll be trivially broken by a multi-line logging statement. Any code that can suddenly break due to otherwise-legal reformatting is best avoided.

Next we have

... which still results in it being visible in the disassembly ...

which shouldn't be true if the code is genuinely dead, you have a decent compiler, and you turn on optimization. It's still some work, though.

The usual solution is something like

#ifdef NDEBUG
#define LOG(EXPR)
#else
#define LOG(EXPR) std::cerr << EXPR
#endif

This is an alternative, but it's not an alternative such as surrounding all the log code with #if defined, so I don't know if it's a problem for you or not.

It does have the advantage of genuinely compiling to nothing at any optimization level.

Upvotes: 2

Richard
Richard

Reputation: 8920

If your version of C++ handles if constexpr I've come to like things along this line for what you're asking.

#include <iostream>

template <bool Log>
struct LOGGER {
    template <typename T>
    LOGGER& operator<<(T const &t) {
        if constexpr (Log)
            std::cout << t;
        return *this;
    }
};

LOGGER<false> LOG;

int main (int argc, char const* argv[])
{
    LOG << "A log statement." << '\n';
    return 0;
}

Upvotes: 4

Jolly Jose
Jolly Jose

Reputation: 84

Better logic would be to define tracer policy, where you can set the logging level at the start of the application and then use the tracing level to make the decision to either log the degug information. Tracing level can be defined as an enum like

enum Tracelevel{CRITICAL, ERROR, INFO, TEST, DEBUG};

setTraceLevel(TraceLevel trcLvl){
    _traceLevel = trcLvl;
};

#if defined _DEBUG
if(_traceLevel  == DEBUG) {\
#define LOG std::cout
}
#endif

A lightweight logger can be found http://www.drdobbs.com/cpp/a-lightweight-logger-for-c/240147505?pgno=1

Upvotes: -1

Related Questions