How can track execution in C++ without using a debugger? - c++

I have a simple C++ program;
int someFunction()
{
cout << "Testing here" << endl;
cout << "reached here in function " << __LINE__ << " in " << __FUNCTION__ << endl; // debug purposes
// do some more stuffs here
cout << "reached here in function " << __LINE__ << " in " << __FUNCTION__ << endl; // debug purpsoes
}
Is there a way of switching on/off the lines of codes marked as "debug purposes"? The ideas is in case of problems I can just write a one liner to switch on those kind of debug purpose codes and when solved switch them off.
I know debuggers are for this very purpose, but want something simple for simple programs.

You can wrap it in a conditional define:
#ifndef NDEBUG
// Debugcode here
#endif
When you are done debugging, just define NDEBUG during compilation. You might also want to have a look at assert. It is controlled by the same macro NDEBUG and easily lets you check conditions in you program. You can also have it produce meaningful error messages:
assert(allWentWell && "Blah went wrong!");
The error-message of assert will also include information to where the error occurred.

The classical way to solve this is to define some logging macros; a simple example may be:
#ifdef_NDEBUG
# define LOG(X)
#else
# define LOG(X) do { std::clog<<__FILE__<<":"<<__LINE__<<" "<<(X)<<std::endl;} while(0)
#endif
Usage:
LOG("Before frobbing the widget (i="<<i<<")");
Of course this can be taken to any level of complexity (there are quite a few libraries that approach the problem of logging).

In addition of the other replies, you could declare a global flag:
#ifndef NDEBUG
bool want_debug;
#endif /*NDEBUG*/
then define a macro
#ifndef NDEBUG
#define DEBUG_OUT(Expr) do {if (want_debug) \
cout << __FILE__ << ":" << __LINE__ << " " \
<< Expr << endl;} while(0)
#else
#define DEBUG_Out(Expr) do{}while(0)
#endif
and you'll add a lot of statements like
DEBUG_OUT("here x="<< x);
The want_debug flag could be set at runtime (e.g. inside a debugger, or with some -d program argument handled by your main). If you compile with -DNDEBUG you won't get any code for DEBUG_OUT statements.
I'm using the NDEBUG preprocessor symbol related to the old assert(3).
Of course, be careful to avoid meaningful side-effects in DEBUG_OUT, e.g. DEBUG_OUT("here y=" << y++); /*WRONG side effect*/ is certainly a mistake.
If using a recent GCC compiler (e.g. g++ version 4.9), you could also customize it using MELT by adding magically (in your customizing extension coded in MELT) some pass which would automatically add logging messages (e.g. at end of every routine). But that might means weeks of work (so is worthwhile for big existing software projects).

Is you want to "switch on/off" some part of code, you can use macros and preprocessor directives #ifdef and #endif:
#ifdef _DEBUG
//run this code
#endif
Above code will only run, if _DEBUG macro is defined:
#define _DEBUG

Related

How to use preprocessor IF on DEFINE that is an ENUM member?

I am struggling with this for a while now, and cant get it to work!
I have a preprocessor define for LOG_LEVEL which defines what logs my program should emit.
I Have a lot of LOG points, so performance is needed,
therefore, no use of runtime check for log_level.
I trimmed my code to the minimal problematic construct which can be played with (here)[https://onlinegdb.com/u39ueqNAI]:
#include <iostream>
typedef enum {
LOG_SILENT=0,
LOG_ERROR,
LOG_WARNING,
LOG_INFO,
LOG_DEBUG
} E_LOG_LEVELS;
// this define is set using -DLOG_LEVEL=LOG_WARNING to the compiler.
#define LOG_LEVEL LOG_WARNING
int main() {
std::cout << "Logging Level Value is " << LOG_LEVEL << std::endl; // output 2 (correctly)
#if LOG_LEVEL==LOG_WARNING
std::cout << "Log Level Warning!" << std::endl; // outputs (correctly)
#endif
#if LOG_LEVEL==LOG_ERROR
std::cout << "Log Level Error!" << std::endl; // outputs (Why ??? )
#endif
return 0;
}
The main issue is that the #if LOG_LEVEL==LOG_* always true.
I also tried #if LOG_LEVEL==2 but this returned FALSE (uff).
what's going on ?
how can I test that a define is an enum value ?
You don't need the preprocessor for this. A normal
if (LOG_LEVEL <= LOG_WARNING)
will not create a runtime test when the condition involves only constants and the build has any optimization at all.
Modern C++ allows you to force the compiler to implement the conditional at compile-time, using if constexpr (...). This will prune away dead branches even with optimization disabled.
Finally, if you insist on using the preprocessor, and you can guarantee that the macro will use the symbolic name (you'll never build with g++ -DLOG_LEVEL=2), then you can
#define STRINGIFY(x) #x
#define STRINGY2(x) STRINGIFY(x)
#define PP_LOG_LEVEL STRINGY2(LOG_LEVEL)
#define LOG_LEVEL_IS(x) STRINGY2(LOG_LEVEL)==STRINGIFY(x)
then either
#if PP_LOG_LEVEL=="LOG_WARNING"
or
#if PP_LOG_LEVEL_IS(LOG_WARNING)
But I would recommend avoiding preprocessor string comparison for this.
If you do use the preprocessor, I recommend checking the actual value against a whitelist and using #error to stop the build in case LOG_LEVEL isn't set to any of the approved names.

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:
Overloading the leftshift operator for void as an inline constexpr that does nothing (which still results in it being visible in the disassembly; I don't want that)
Defining LOG as: #define LOG //, but the comment identifier isn't substituted in
Any ideas? Like I said earlier, I don't want any alternatives, such as surrounding all the log code with #if defined _DEBUG
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;
}
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.
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.
#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
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

Is it possible to replace the whole line with #define?

Let's assume that I have a program with many files and many cout's, and for debug purposes I would like to disable output for a moment, but only in a single file.
It is just out of curiosity question, I know that I shouldn't do that to disable output, but I started to wonder when facing this problem, and it only shows properly what I mean.
I tried to create a #define macro, but I can't replace the whole line, only a single symbol (with params).
For example:
//some common header file
#ifdef DISABLE_OUTPUT
#define cout... void; //?? DK exactly what should i put here
#endif
//other file
#include "commons.h" //my macro
#define DISABLE_OUTPUT
void foo()
{
...
cout << "blablabla" << 4 << "something" << endl; // should be removed
...
}
If DISABLE_OUTPUT is defined, the whole line should be replaced with void; (better clear the line).
The problem is that I don't know how to clear the whole line with #define.
Is there any "magic" symbol or trick that I can use?
It’s a bad idea to define a macro with the same name as a standard library component, so you shouldn’t #define cout at all. I’m going to assume you #define disableable_cout instead.
The simplest answer would be to define it like this:
#ifdef DISABLE_OUTPUT
#define disableable_cout if (false) cout
#else
#define disableable_cout cout
#endif
And then update the cout line in foo to this:
disableable_cout << "blablabla" << 4 << "something" << endl;
Which would expand to either this:
if (false) cout << "blablabla" << 4 << "something" << endl;
if DISABLE_OUTPUT is defined, or to this:
cout << "blablabla" << 4 << "something" << endl;
if DISABLE_OUTPUT were not defined.
Then, if DISABLE_OUTPUT is defined, the output line is skipped; if not, it will happen.
Alternately, you could require DISABLE_OUTPUT is always defined, to either 0 (don’t disable) or 1 (do disable). Then you could use a single definition, like this:
#define disableable_cout if (!DISABLE_OUTPUT) cout
Note that, either option is fragile, like most macros, but it should work in the typical case.

#define directives not working outside main() function

I just started learning C++ today. With previous knowledge in other languages I am doing fine so far, but I am confused about #define directives.
I have this code in my "review" C++ file:
#include <iostream>
#define TEST //object-like macro
#ifdef TEST //if TEST is defined
std::cout << "This works!" << std::endl;
#endif
#ifndef NOT_TEST //if NOT_TEST is NOT defined
std::wcout << "This also works!" << std::endl;
#endif
int main()
{
//program code
}
The above code produces errors, first one being syntax error : mssing ';' before '<<'. When I move the #define/#if directives into the main loop, it works properly:
#include <iostream>
int main()
{
#define TEST //object-like macro
#ifdef TEST //if TEST is defined
std::cout << "This works!" << std::endl;
#endif
#ifndef NOT_TEST //if NOT_TEST is NOT defined
std::wcout << "This also works!" << std::endl;
#endif
}
What about the first block of code is incorrect? based on the tutorial I am using, I thought that was how it was supposed to be formatted?
EDIT: I've updated my code to be more clear.
This has nothing to do with formatting. In fact, C++ files are formatting-agnostic. The problem is that after the pre-processor parses your file, you end up with 2 cout statements outside the main function. In C++ you cannot have standalone statements outside of a function, except for declarations/definitions.
You should understand that compilation of a C++ program is a two-step process. First the preproccessor is executed that transforms the file according to instructions you gave it (those that start with #). Then the C++ compiler is executed on the resulting file.
The “code relating to the preprocessor” here is just the #ifdef/#ifndef (with the condition that follows it immediately) and #endif keywords and, indeed, you can put those wherever you like, since preprocessor doesn’t care about C++ syntax, it performs straightforward string operations.
When the preprocessor runs it plugs your C++ code between #ifdef and #endif into the file, so the effect is the same as if you just had the cout << … line (outside the main function).
So, since TEST is defined and NOT_TEST is not, after the preprocessor did its job you are left with a file that has just two lines:
std::cout << "This works!" << std::endl;
std::wcout << "This also works!" << std::endl;
If you try to compile it, you’ll see that the compiler is not happy, because that’s, obviously, not a valid C++ program.
The Problem is using of cout << out of main function.
If you wanna have any output line you can use #error directive to abort compilation process.

How to remove log debugging statements from a program

I am using boost::log as a logger for my C++ program.
During development I often use it this way, for example:
#define LOG(severity) BOOST_LOG_SEV(boost::logger::get(), (severity))
#define LOG_ERR LOG(Severity::error)
#define LOG_INFO LOG(Severity::info)
#define LOG_DEBUG LOG(Severity::debug)
where BOOST_LOG_SEV is the facility provided by boost::log, while LOG, LOG_ERROR, LOG_INFO, LOG_DEBUG are shortcuts defined by me.
In short, BOOST_LOG_SEV dynamically compares the current debugging severity with the severity passed to the macro itself to decide whether to emit the output or not.
This is an example of a program which use the above macros for debugging purposes:
// set at compile time
#define MAX_LOG_SEVERITY Severity::debug
int main() {
// Print all the messages with a
// Severity <= MAX_LOG_SEVERITY defined before compiling
boost::log::set_severity(boost::logger::get(), MAX_LOG_SEVERITY); // set_severity() is fictitious just to give you an idea
// bool err = ...
if (err)
LOG_ERR << "An error occurred";
else
LOG_INFO << "Okay;
LOG_DEBUG << "main() called";
}
Now, when releasing the program for a production environment, debugging messages with a Severity::debug level do not really make sense. I could hide them from the output by simply decreasing MAX_LOG_SEVERITY to Severity::info, but the problem is that the calls made by LOG_DEBUG will not be removed from the executable code. This has a bad impact on both efficiency and object size.
The code is full of logging statements and I'd really like to preserve the simple use of operator<<().
Without touching those statements themselves, is there any better macro definition/trick for LOG_DEBUG that would make the pre-processor or the compiler (during its optimizations) "skip" or "remove" the debugging statements when MAX_LOG_SEVERITY is set to the Severity::debug constant ?
While I can't make any guarantees, something like this might work. It depends on what your optimizer does and whether or not you have side effects in the parameters to operator<<.
#ifdef NO_LOG_DEBUG
static class DevNull
{
} dev_null;
template <typename T>
DevNull & operator<<(DevNull & dest, T)
{
return dest;
}
#define LOG_DEBUG dev_null
#else
#define LOG_DEBUG LOG(Severity::debug)
#endif
#MartinShobe's accepted answer works on:
g++ (4.7.2) with -O1 and higher
clang++ (3.4) with -O2 and higher
Visual Studio (2008) with linker flag /OPT:REF
The accepted answer does not work for me (MSVC 2019, stdc++17).
My solution is a bit whacky though. But the optimization should definitely take care of it:
#ifdef NDEBUG
#define LOG_DEBUG if (false) std::cout
#else
#define LOG_DEBUG if (true) std::cout
#endif
Usage:
LOG_DEBUG << ... << std::endl;
Turns off all optimizations in the program and speeds compilation.
/Od
or boot_log_stop