Блог пользователя Anshul_Johri

Автор Anshul_Johri, 4 месяца назад, По-английски

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

  • Проголосовать: нравится
  • +241
  • Проголосовать: не нравится

»
4 месяца назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

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

»
4 месяца назад, # |
  Проголосовать: нравится +36 Проголосовать: не нравится

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
»
4 месяца назад, # |
Rev. 3   Проголосовать: нравится -7 Проголосовать: не нравится

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

UPD: Sorry for saying something too wrong...

  • »
    »
    4 месяца назад, # ^ |
      Проголосовать: нравится +3 Проголосовать: не нравится

    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

  • »
    »
    4 месяца назад, # ^ |
      Проголосовать: нравится +8 Проголосовать: не нравится

    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
»
4 месяца назад, # |
  Проголосовать: нравится +6 Проголосовать: не нравится

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

»
4 месяца назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

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

  • »
    »
    4 месяца назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

    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.

    • »
      »
      »
      3 месяца назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      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.

»
4 месяца назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

No print tuple 😢

  • »
    »
    4 месяца назад, # ^ |
    Rev. 2   Проголосовать: нравится +8 Проголосовать: не нравится

    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
»
4 месяца назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

Not Wokring for iterator

e.g:-

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

  • »
    »
    4 месяца назад, # ^ |
      Проголосовать: нравится +9 Проголосовать: не нравится

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

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

»
3 месяца назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

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

Template
  • »
    »
    3 месяца назад, # ^ |
    Rev. 2   Проголосовать: нравится +11 Проголосовать: не нравится

    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
»
3 месяца назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

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

»
3 месяца назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

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

»
3 месяца назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

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

»
3 месяца назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

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

  • »
    »
    3 месяца назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

    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.

»
3 месяца назад, # |
  Проголосовать: нравится +4 Проголосовать: не нравится

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

»
3 месяца назад, # |
Rev. 2   Проголосовать: нравится +3 Проголосовать: не нравится

Gonna leave this here

»
3 месяца назад, # |
  Проголосовать: нравится +5 Проголосовать: не нравится

When used for queue it clears the queue.

  • »
    »
    3 месяца назад, # ^ |
    Rev. 2   Проголосовать: нравится +1 Проголосовать: не нравится

    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 (>︿<)

»
3 месяца назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

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

  • »
    »
    3 месяца назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    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.

»
3 месяца назад, # |
  Проголосовать: нравится +1 Проголосовать: не нравится

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

»
3 месяца назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

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
»
3 месяца назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

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

  • »
    »
    2 месяца назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    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
    • »
      »
      »
      2 месяца назад, # ^ |
      Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

      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

      • »
        »
        »
        »
        2 месяца назад, # ^ |
          Проголосовать: нравится +12 Проголосовать: не нравится

        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.

        • »
          »
          »
          »
          »
          2 месяца назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится

          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.

          • »
            »
            »
            »
            »
            »
            2 месяца назад, # ^ |
            Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

            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
            • »
              »
              »
              »
              »
              »
              »
              2 месяца назад, # ^ |
                Проголосовать: нравится 0 Проголосовать: не нравится

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

»
3 месяца назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

I have a debug template too:

»
2 месяца назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Thanks

»
2 месяца назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

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?

  • »
    »
    2 месяца назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    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

    • »
      »
      »
      2 месяца назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      See the Picture.

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

      • »
        »
        »
        »
        2 месяца назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        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

        • »
          »
          »
          »
          »
          2 месяца назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится

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

»
2 месяца назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

How does type name output working?

»
2 месяца назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

how to set up this template on sublime??

  • »
    »
    2 месяца назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    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.

»
2 месяца назад, # |
  Проголосовать: нравится +3 Проголосовать: не нравится

Thanks brother for the template :)