Mikel_Arteta_8's blog

By Mikel_Arteta_8, history, 15 months ago, In English

Hi everyone.

This is my template for debugging in C++. I was inspired by Tourist's source code and modified it to my style. Here is it:

Template

To debug, just type: debug(x, y, z...). It requires C++ 11 or above.

It can work with:

  • Primitive data types: bool, int, long long, float, ...

  • std::pair, std::string

  • Collection types: std::vector, std::map, std::set, ...
  • Expressions

It also support multiple arguments.


How to use

Primitive data types:

bool a = true;
debug(a);

int b = 1;
float c = 2.5;
long long d = LLONG_MAX;
char e = 'e';
debug(a, b, c, d, e);

Output:
'[a] = [true]'
'[a, b, c, d, e] = [true, 1, 2.5, 9223372036854775807, 'e']'

std::pair and std::string:

pair<int, int> a = {1, 2};
pair<string, bool> b = {"abcd", false};
pair<char, float> c = {'x', 0.5};
string d = "This is a string";
pair<int, pair<int, int> > e = {1, {2, 3}};
debug(a, b, c, d, e);

Output:
'[a, b, c, d, e] = [{1, 2}, {"abcd", false}, {'x', 0.5}, "This is a string", {1, {2, 3}}]'

Note: You should only debug a pair of simple data types. For example, the debug won't work if one of pair's elements is collection type (std::vector, std::map, std::set...).


Collection types:

Basically, the debug works with collections types which you can iterate by for (auto i: a). So the debugger won't work with collection types like std::queue or std::stack.

vector<int> a = {1, 2, 3, 4};
set<int> b = {1, 2, 2, 3, 3, 4, 4, 5};
map<string, int> c;
c["string 1"] = 1;
c["string 2"] = 2;
debug(a, b, c);

unordered_map<string, int> d;
d["string 3"] = 3;
d["string 4"] = 4;
multiset<int> e = {5, 5, 4, 3, 1, 1, 2};
vector<vector<int> > f = {{1, 2, 3}};
debug(d, e, f);

Output:
'[a, b, c] = [{1, 2, 3, 4}, {1, 2, 3, 4, 5}, {{"string 1", 1}, {"string 2", 2}}]'
'[d, e, f] = [{{"string 4", 4}, {"string 3", 3}}, {1, 1, 2, 3, 4, 5, 5}, {{1, 2, 3}}]'

Note: I haven't tried the debug with other complex data types nested in collection types.


Expressions:
int a = 1;
int b = 2;
debug(a + b, a * b, a / b, a - b, a / (float)b, 2019, 2019 - 1);

Output:
'[a + b, a * b, a / b, a - b, a / (float)b, 2019, 2019 - 1] = [3, 2, 0, -1, 0.5, 2019, 2018]'


You can use the template and change it's style to what you want. Hope it would help you debug in C++ easier.

 
 
 
 
  • Vote: I like it
  • +39
  • Vote: I do not like it

»
15 months ago, # |
  Vote: I like it 0 Vote: I do not like it

You could

replace this
with this
»
15 months ago, # |
  Vote: I like it 0 Vote: I do not like it

Auto comment: topic has been updated by livw (previous revision, new revision, compare).

»
14 months ago, # |
  Vote: I like it 0 Vote: I do not like it

Thank you brother livw !!!

»
13 months ago, # |
  Vote: I like it 0 Vote: I do not like it

Have you compared it with this template for debugging which is also based on a submission by tourist? If yes, then how does it compare?

  • »
    »
    13 months ago, # ^ |
    Rev. 2   Vote: I like it 0 Vote: I do not like it

    Also, how is your template better than what tourist used?

    I can see how it is worse: in your #define it would be better to use a comma instead of a semicolon so that it is treated as one statement if it is not enclosed in braces for example as the body of a for loop.

»
5 months ago, # |
  Vote: I like it 0 Vote: I do not like it

Does not work for vector :( And of course for arrays

»
3 months ago, # |
  Vote: I like it 0 Vote: I do not like it

amazing, i just learn c++ template, and then i find these good stuffs.

»
3 months ago, # |
  Vote: I like it 0 Vote: I do not like it

How can I add this to vscode such that when I create a new cpp file in Vscode, the template gets loaded directly or any shortcut rather than copy paste everytime?

  • »
    »
    3 months ago, # ^ |
      Vote: I like it +3 Vote: I do not like it

    You can use snippets in vs code for this purpose... You can find this in settings gear icon...

»
4 weeks ago, # |
  Vote: I like it 0 Vote: I do not like it

when I am copy pasting this template I am getting error like undefined reference to std::cerr how do I fix this ?

  • »
    »
    4 weeks ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    may be your compiler is not above C++11. Please check that out .

    • »
      »
      »
      4 weeks ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      Oh I found my mistake it was a stupid one though I used gcc instead of g++ lol old habits used to C language. But still thankyou!

»
4 weeks ago, # |
  Vote: I like it 0 Vote: I do not like it

Doesn't work with arrays. How can I modify it to work with arrays?

  • »
    »
    4 weeks ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    The function template template <typename T, typename... V> void _print(T t, V... v) takes its arguments by value. Arrays cannot be copied and are instead treated as pointers. Pointers don't know the size of the underlying array and thus do not support std::begin and std::end. Range-based for-loops, however, require these two functions.

    To prevent the decay, _print should take its arguments by reference. You can either use lvalue references _print(T const& t, V const&... v), or forwarding references _print(T&& t, V&&... v). The latter is usually preferred, but here it doesn't make a difference. In both cases, you avoid the costly copying in the recursion.

»
4 weeks ago, # |
Rev. 2   Vote: I like it 0 Vote: I do not like it

The same thing can be achieved by overloading ostream for STL containers (this way nested structures work too). Also, you can come up with some pretty neat one liners using fold expressions and lambdas.

Spoiler

If you'd like a more generic reader-writer/debugger template (using SFINAE) for C++ STL, you can look at submissions by @Narut on CF.

»
3 weeks ago, # |
  Vote: I like it 0 Vote: I do not like it

This is super helpful Thanks! But can you tell me how to redirect the cerr output to a file.. I do it with the command freopen("error.txt", "w", stdout ) but for multiple variables, it's showing the output on the terminal

  • »
    »
    3 weeks ago, # ^ |
    Rev. 2   Vote: I like it 0 Vote: I do not like it

    freopen("error.txt", "w", stderr);

    cin — stdin

    cerr — stderr

    cout — stdout