Anshul_Johri's blog

By Anshul_Johri, 9 months ago, In English

C++ Debug Template 🛠

Simplify variable tracking across functions and loops!

Longer Template (std >= C++11)
Shorter Template, (std >= C++20)

As of now both perform equally well, but my choice? C++20.


Simple Usage

This template supports datatypes such as:

  🔢 Primitive: int, char, bool, long long int etc.

  📚 STL: pair, tuple, vector, set, oset, map, omap, stack, queue, priority_queue, bitset etc.

  📦 Arrays of all datatypes: int arr[], bool arr[], vector<int> adj[] etc.

  🧩 Matrix: int dp[100][200], vector<vector<bool>> vis(100, vector<bool> (200, 0)) etc.

  🕗 Arrays that have been decayed or declared at runtime like int arr[n].

  📝 Rvalue Literals like "Hello", false, 'z', isSafe(i, j), dfs(u).

  🧱 User defined structs / classes like Point, Node.

  🤯 Even nested datatypes like map<string, vector<pair<char, unordered_set<long long>>>> WHATTT;.

Note: For latest updates and a colored stderr version of this template, visit my Github.

Colored Template Preview

How to use it?

Let's say you have different datatypes such as:

Example

You can debug them like this debug(var1, var2, var3, var4, ...);

Example

If you have user defined structs / classes, you just need to make a print() function, and use debug(...) like you do :)

User-Defined struct/class printing.

In instances where array have decayed into pointer, or you declared array at runtime, use debugArr(arr, n);

What is Array Decay?

Note:

  • You don't need to remove debug(...) statements in your code when submitting it.
  • On platforms like Codeforces, there's a macro called ONLINE_JUDGE that's defined, automatically disregarding all your debug statements. This ensures your solution will be accepted unless there's a logical error.

How to Setup?

  • Copy this template into your own templates. The output will be directed to the stderr stream.
  • Alternatively you can make a separate header file and include this into your template
    #ifndef ONLINE_JUDGE
    #include "template.cpp"
    #else
    #define debug(...)
    #define debugArr(...)
    #endif
  • When using it for LeetCode uncomment #define cerr cout and before submitting change #ifndef to #ifdef to ignore debug(...);. For convenience, after changing it, copy it, and keep it pinned in your clipboard for repetitive use.

For Complete Beginners who need step by step tutorial (for VS Code), follow these steps:

Steps

If you liked this blog, please upvote it, I'd really be grateful :)

Edit: Looking for something unique and fun? Check out my other blog on How doing CP and GYM are Alike

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

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

Unexpectedly high quality and kinda useful blog from a specialist (sounds as a ratism, yeah), great work!

»
9 months ago, # |
  Vote: I like it +36 Vote: I do not like it

I just want to note, it's probably not a good idea to copy paste this entire template into ur submission, instead store it in a header or something. Then you can do something like

#ifdef LOCAL
#include "path/debugtemplate.cpp"
#else
#define debug(...)
#endif
»
9 months ago, # |
Rev. 3   Vote: I like it -7 Vote: I do not like it

Great post! And any way to incorporate pbds (oset, omap) would be nice...

UPD: Sorry for saying something too wrong...

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

    My solution was to manually go into the ext/pb_ds/assoc_container.hpp file and add some debugs at the very bottom so u can just do cout << os << '\n';.

    My Code

    Im not an expert with how the arguments actually work, I just know it works on my own end. If someone here has any better solutions, please share

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

    We don't need to explicitly make one for oset/ omap, as they can be iterated through range-based for loops, so this section will print it automatically.

    Spoiler
»
9 months ago, # |
  Vote: I like it +6 Vote: I do not like it

High-quality and useful content! Keep it up :)

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

If multiple people keep using it, won't they get plagiarism because of same template?

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

    If the rest of your code doesn't have significant coincidence with the other person, no. But there is a small chance of it happening.

    • »
      »
      »
      9 months ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      Do plagiarism detector also takes care of already published codes? Let's say a person is using already published codes of Trie or segment tree or even this template, will they get plagiarism because of it? How does that work out? Because they definitely coincide.

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

No print tuple 😢

  • »
    »
    9 months ago, # ^ |
    Rev. 2   Vote: I like it +8 Vote: I do not like it

    Thanks for pointing it out, I never used tuple so didn't think I needed that. Now I've updated the code above, try it again and it'll work.

    Changes I made
»
9 months ago, # |
Rev. 2   Vote: I like it 0 Vote: I do not like it

Not Wokring for iterator

e.g:-

multiset m3; m3.insert(3); auto it2 = m3.lower_bound(1); debug(it2);

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

    We don't debug it directly, instead, we debug what it is referencing.

    Experiment with using debug(*it) and it works perfectly fine.

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

I'm just wondering, does this have any advantage over Benq's debug template ?

Template
  • »
    »
    9 months ago, # ^ |
    Rev. 2   Vote: I like it +11 Vote: I do not like it

    Definitely yes, you can test it for yourself.

    • This template displays Line Number and Variable Names before their values
    • This template supports much more datatypes than BenQ's template
    • This template provides properly formatted output to enhance readability with appropriate brackets and commas.

    Here are some Datatypes that you can test.

    Spoiler

    My template supports all these datatypes, but the following datatypes (which are commented) aren't supported by BenQ's template.

    Spoiler

    You can compare both outputs here:)

    Spoiler
»
9 months ago, # |
Rev. 2   Vote: I like it 0 Vote: I do not like it

He is an ally you fools. And you are indigo too.

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

Great template. It would be nice if we could debug Structs as well. Is it doable?

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

I have written a blog on using a debugging template quite some time back. You all can have a look at it as well: https://cs-mshah.github.io/getting_started_with_cp/#debugging

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

Why does the std >= C++20 version give a CE (an error on line 14) when compiling with -D_GLIBCXX_DEBUG flag?

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

    Edit:
    Internally vector<bool> is optimized and uses _Bit_reference instead of bool to conserve space and provide same functionality.

    Therefore, we can overload vector<bool> itself. Issue has been fixed now. Thanks.

»
9 months ago, # |
  Vote: I like it +4 Vote: I do not like it

Awesome bro.. This will surely help me a lot..

»
9 months ago, # |
Rev. 2   Vote: I like it +3 Vote: I do not like it

Gonna leave this here

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

When used for queue it clears the queue.

  • »
    »
    9 months ago, # ^ |
    Rev. 2   Vote: I like it +1 Vote: I do not like it

    Thanks for pointing out. I just made a silly mistake in std=c++20.

    Instead of doing auto temp = x, I did T temp = x where T evaluated to queue<int> &&q
    It's now fixed :)

    Edit:
    Oops! Imagine the panic when contestants realize their precious queues, stacks, or priority_queues are pulling a vanishing act mid-contest!

    What do I do now to fix this? I hate myself (>︿<)

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

Bro, Anshul_Johri "Shorter Template, (std >= C++20)" is it cause any problem in Judges where C++20 is not supported?

  • »
    »
    9 months ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    The Shorter Template utilizes new features from C++20. To debug it on your computer, ensure you activate the compiler flag -std=C++20. If you're not placing this template in a header file and it constitutes your entire source code, simply ensure that #ifndef ONLINE_JUDGE is placed at the beginning of your template. This will allow you to use an older version of C++ when uploading your code online. However make sure to test this beforehand.

»
9 months ago, # |
  Vote: I like it +1 Vote: I do not like it

I'm new to CP, though I've done DSA. I'm going to use your template in my first contest 😄

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

When printing vector<vector<int>>, I can see row-index, can you change it to enable to see column-index too?

Current
With j-index
»
9 months ago, # |
  Vote: I like it 0 Vote: I do not like it

Good! I think it is a good idea to add a template for stress-testing to it.

  • »
    »
    8 months ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    I'm not really an expert in stress testing (no pun intended). I have simple folder with these files:

    Correct.cpp, Wrong.cpp, Generator.cpp, Checker.cpp and script.sh

    I run script.sh from terminal, and it generates input.txt, outputCorrect.txt, outputWrong.txt. And Checker.cpp compares those files. It only tells the line number, and prints the line where it failed. But it doesn't tell the test case number. I have to figure that out myself by looking at input.txt. Eventually I find it, but it's too time consuming and therefore I only use it when practicing. Please tell me if you've found/have a better stress tester.


    Generator.cpp
    Checker.cpp
    script.sh
    • »
      »
      »
      8 months ago, # ^ |
      Rev. 2   Vote: I like it 0 Vote: I do not like it

      I have written stress-tests many times, because I like making bugs in my code. But I always write all stress tests in the same file. Recently I made a template for this:

      Code

      But, in case these functions are usually very simple, like

      for (int i = 0; i < n; i++) a[i] = rnd() % 100 for make_data, it is also a good way to implement it every time you need it without writing separate functions.

      P.S. If it wasn't code for competitive programming, others would kill me

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

        I never thought about stress testing within the same file. You inspired me to make one, and I did make one today. Though it uses 2 cpp files for a cleaner implementation and less clutter, it is also very easy to use (can be used during contests). I plan to make a blog about it, but only after I've tested it well enough. It also tells you the exact testcases where the code is failing. It can also work on multi answer problems (Need custom checker function though). But I also want it to work with interactive problems. I'm working on that part. Because stress testing interactive problems is a nightmare.

        • »
          »
          »
          »
          »
          8 months ago, # ^ |
            Vote: I like it 0 Vote: I do not like it

          Great!

          What about interactive problems, I have written stress test to only one of them. It is usually enough to check if the output fits some constraints, like the number of queries, and gives you correct answer.

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

            I finally made a blog for this. I'd really appreciate if you give feedback on it there.

            Edit: I deleted the blog, probably people prefer using multiple files for stress testing. But here's the code I made.

            solution.cpp
            stressTest.cpp

            All these functions will be filled using cin, cout. No need to return anything. their outputs would be saved in stringstreams and worked upon appropriately. When we run it, it would should you the exact testcase it failed, along with expected output and received output.

            Draft of blog
            • »
              »
              »
              »
              »
              »
              »
              8 months ago, # ^ |
                Vote: I like it 0 Vote: I do not like it

              Good. I but if your solution use global varialbes, it is nice to add clear function which clears all global vectors, sets, etc.

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

I have a debug template too:

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

Thanks

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

It works fine in VScode. But it does not show debug output in Leetcode. I have done all the steps mentioned in the blog for the Leetcode. What could I have done wrong?

  • »
    »
    8 months ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    When using it for LeetCode uncomment #define cerr cout and before submitting change #ifndef to #ifdef to ignore debug(...) and prevent TLE. For convenience, after changing it, copy it, and keep it pinned in your clipboard for repetitive use.

    It is because Leetcode doesn't support stderr, but it supports stdout

    • »
      »
      »
      8 months ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      See the Picture.

      I have uncommented (#define cerr court) code on the clipboard.

      • »
        »
        »
        »
        8 months ago, # ^ |
          Vote: I like it 0 Vote: I do not like it

        Look, the actual code is in template.cpp. But when you are on LeetCode, there's no template.cpp file there to access it, it's only in your local computer. When I said copy the template, I meant the actual code.

        Paste this only

        Now paste this above your solution class. And it'll work fine. My leetcode submission

        • »
          »
          »
          »
          »
          8 months ago, # ^ |
            Vote: I like it 0 Vote: I do not like it

          Now I understood. Thank you very much. This template is very helpful. Now, I can debug my code very easily than ever before.

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

How does type name output working?

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

how to set up this template on sublime??

  • »
    »
    8 months ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    Just keep a file like template.cpp in your current directory which have this template.

    Then have this in your main file.

    #ifndef ONLINE_JUDGE
    #include "template.cpp"
    #else
    #define debug(...)
    #define debugArr(...)
    #endif
    

    If you're asking about how to make a code snippet, refer this. To make snippets fast and easy, I use this website.

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

Thanks brother for the template :)

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

Can somebody help me , I can't use Cpp20 in my vs code , how can i make my vs code use cpp20 and also I am not getting colored output in "cph" STANDARD ERROR , but if i run in my terminal , then its colored , is there a way to fix it . can it be possible that i will keep using cph while the debug will happen in the terminal of vs code not in cph ,

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

Please can someone explain how the debug template works and why we should use it?

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

    As they say, best way to debug is to use print statements, and OP has created a general purpose debug functions, which can print anything which is slapped inside it's arguments (pretty much). So yeah, really cool stuff!

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

Really cool!

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

small typo , give space in cpp11 file in line 162 after "||"

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

debug(1 << a, b) breaks it