Pretty and powerful 4-line code for debugging (C++17 edition)

Revision en12, by Sanitator, 2019-02-17 19:19:24

Debugging the traditional way

Virtually every competitive programmer sometimes needs to print the values from some container, or array, or just a variable during debugging. This is where appear those ugly nested loops which take several minutes to write:

vector<int> a[2][2] = {{{2,3}, {4}}, {{6,2}, {4,5}}};
    for(int i = 0; i < size(a); ++i, cout << endl){
        for(int j = 0; j < min(4, int(size(a[i]))); ++j, cout << endl){
            for(int k = 0; k < min(3, int(size(a[i][j]))); ++k){
                cout << a[i][j][k] << ' ';
            }
        }
    }

OMG, and bound checking for simple output of an array of vectors? 2D, 3D, it doesn't matter anymore if we can't write it concisely.

Debugging with f_dbg()

I was fed up with traditional this and wrote a simple 4-liner for printing almost everything one might want. The output is in python style. It has some limitations, but generally I like it.

You can find it here. My code exploits C++17 features, so choose the appropriate compiler.

How formatted debug works

Let me call c-array, vector, deque, array just arr. Then, basically, f_dbg() can output sub-arr. To print sub-arr, you pass coordinates of its start and the coordinates of its end, id est, of the cells with the smallest and the largest coordinates of sub-arr. If they are too large, f_dbg() reduces them, so that they are inside the arr. By default the starting cell is the first cell of arr, last cell — the last cell of arr.

If type of element of arr is some other arr-type, f_dbg() is recursively called with this element as argument until the simplest types are reached. You know them: int, char, double, and so on. They are then neatly printed, and that's all.

Other data structures like maps, sets don't have any indices, that's why they are printed from begin to end. In maps, f_dbg()is called both from the key and the value.

Pairs are printed the same way — recursive f_dbg() from the first element and from the second.

For example:

vector<vector<string>> d = {{"fjs", "sdf"}, {"sas"}};
f_dbg(d);

output: [[fjs,sdf],[sas]]

/*-----------------------------------------------*/

It is better to print the main types with macro function _(). It uses the syntax of dbg() function and just substitutes the bare variable with its name, colon, value, and comma. It's created only to not write cout << "a: " << a << "," every time; It looks like this:

string s = "Hello, world!";
dbg(_(s));

output: s: Hello world,

/*-----------------------------------------------*/

Hope this code saves your precious minutes during contests. Enjoy.

P.S. if you want to look at the extended version and suggest any improvements, you can find it here.

P.P.S. If you want to adapt this code to c++11 or 14, I don't mind if you clone this blog for (c++11/14 edition). Alternatively, you can suggest me your code to add to this post, so that all versions are together.

UPD: output of unsigned int, long long, unsigned long long, long double, double added

Tags tricks, debug, c++, dbg

History

 
 
 
 
Revisions
 
 
  Rev. Lang. By When Δ Comment
en47 English Sanitator 2019-04-24 07:31:49 76
ru35 Russian Sanitator 2019-04-24 07:28:00 58
ru34 Russian Sanitator 2019-04-24 07:18:39 82
en46 English Sanitator 2019-04-23 19:51:03 576
ru33 Russian Sanitator 2019-04-23 19:46:43 38
ru32 Russian Sanitator 2019-04-23 19:45:30 38
ru31 Russian Sanitator 2019-04-23 19:43:47 607 Мелкая правка: ' с тестами\n**UPD2**' -> ' с тестами<br>\n**UPD2**'
en45 English Sanitator 2019-03-26 07:30:53 100
ru30 Russian Sanitator 2019-03-26 07:29:17 143
ru29 Russian Sanitator 2019-03-25 20:54:41 80
en44 English Sanitator 2019-03-25 20:53:58 79
en43 English Sanitator 2019-03-25 20:51:05 28
ru28 Russian Sanitator 2019-03-25 20:50:48 28 Мелкая правка: '/permlink/pXG09igiUEuyljHW). Он в зн' -> '/permlink/LMm2u1XmJcp929A1). Он в зн'
ru27 Russian Sanitator 2019-03-25 14:07:10 108
en42 English Sanitator 2019-03-25 14:05:28 77
ru26 Russian Sanitator 2019-03-25 11:56:21 395 Мелкая правка: 'ler>\n\nСпсибо за [э' -> 'ler>\n\nСпасибо за [э'
en41 English Sanitator 2019-03-25 11:53:18 382 Tiny change: '">\n~~~~~ void dbgs(' -> '">\n~~~~~ \nvoid dbgs('
ru25 Russian Sanitator 2019-03-25 11:34:02 14
ru24 Russian Sanitator 2019-03-25 11:33:25 7824 Мелкая правка: ' границ.\n \n~~~~~\n ' -> ' границ.\n\nНапример:\n\n~~~~~\n '
en40 English Sanitator 2019-03-25 11:22:03 2 Tiny change: 'e? Meet three helper f' -> 'e? Meet these helper f'
en39 English Sanitator 2019-03-25 11:20:15 34 (published)
en38 English Sanitator 2019-03-25 10:31:59 556 Tiny change: '-----*/`\n\n[Here's ' -> '-----*/`\n<br>\n[Here's '
en37 English Sanitator 2019-03-25 09:39:55 1
en36 English Sanitator 2019-03-25 09:39:31 2667 Tiny change: '---\n**D**e**B**u**G**\n\nS' -> '---\n**D** e **B** u **G**\n\nS'
en35 English Sanitator 2019-03-25 08:35:39 998
en34 English Sanitator 2019-03-25 07:07:59 690 (saved to drafts)
en33 English Sanitator 2019-03-09 11:24:19 65
ru23 Russian Sanitator 2019-03-09 11:22:17 84
en32 English Sanitator 2019-02-23 11:30:12 2
ru22 Russian Sanitator 2019-02-23 11:30:01 78
en31 English Sanitator 2019-02-23 11:28:48 2 Tiny change: 'n**UPD**: dbgs() added, en' -> 'n**UPD**: `dbgs()` added, en'
en30 English Sanitator 2019-02-23 11:28:13 59
en29 English Sanitator 2019-02-23 09:33:05 72
ru21 Russian Sanitator 2019-02-22 21:08:03 613
en28 English Sanitator 2019-02-22 20:54:23 17 Tiny change: 'sions are known' -> 'sions are constant and are known'
en27 English Sanitator 2019-02-22 20:51:52 10 Tiny change: 'ays whose dimension' -> 'ays whose sizes of dimension' (published)
en26 English Sanitator 2019-02-22 20:48:04 486 (saved to drafts)
en25 English Sanitator 2019-02-22 15:26:18 4
ru20 Russian Sanitator 2019-02-22 14:25:56 0 (опубликовано)
en24 English Sanitator 2019-02-22 14:25:45 3422 Tiny change: 'Hope this code saves you' -> 'Hope this function saves you' (published)
ru19 Russian Sanitator 2019-02-22 13:19:21 468 Мелкая правка: 'рована из полной на сайт' -> 'рована из развернутой на сайт'
ru18 Russian Sanitator 2019-02-21 21:00:57 26 Мелкая правка: '/permlink/IZ7rE5yhOTON3Q8f).\n\nКомп' -> '/permlink/ZuU99yZRY9fB852G).\n\nКомп'
en23 English Sanitator 2019-02-21 21:00:22 417 (saved to drafts)
ru17 Russian Sanitator 2019-02-21 20:48:44 297
ru16 Russian Sanitator 2019-02-21 19:48:46 3666 (сохранено в черновиках)
en22 English Sanitator 2019-02-20 03:06:00 763
ru15 Russian Sanitator 2019-02-20 02:48:59 1026 (опубликовано)
ru14 Russian Sanitator 2019-02-19 15:29:34 159 (сохранено в черновиках)
en21 English Sanitator 2019-02-19 11:38:06 21
ru13 Russian Sanitator 2019-02-19 11:37:04 6 Мелкая правка: 'есконечно писать эти ци' -> 'есконечно набивать эти ци'
ru12 Russian Sanitator 2019-02-19 11:34:06 100
en20 English Sanitator 2019-02-19 11:30:00 27
ru11 Russian Sanitator 2019-02-19 11:29:45 1417 Мелкая правка: '\n\n\n\n\nDebugging with `n_dbg()`' -> '\n\n\n\n\nДебаг с `n_dbg()`'
en19 English Sanitator 2019-02-19 11:11:58 50 (published)
en18 English Sanitator 2019-02-19 10:56:50 1015 Tiny change: '~~~~\n\n\n`/*-' -> '~~~~\n\n\n\n`/*-' (saved to drafts)
ru10 Russian Sanitator 2019-02-18 11:03:17 3 Мелкая правка: ' я сделал четырехстрочни' -> ' я сделал трехстрочни'
ru9 Russian Sanitator 2019-02-18 10:58:49 2
ru8 Russian Sanitator 2019-02-18 10:58:21 1092 (опубликовано)
en17 English Sanitator 2019-02-18 10:40:54 63
en16 English Sanitator 2019-02-18 10:37:16 4
en15 English Sanitator 2019-02-18 10:36:09 6 Tiny change: 'compiler. 3-line ve' -> 'compiler. \nThe 3-line ve'
en14 English Sanitator 2019-02-18 10:34:08 2
en13 English Sanitator 2019-02-18 09:49:25 1303 Tiny change: '~~\n\n\n\nf_dbg() output\n\' -> '~~\n\n\n\n`f_dbg()` output\n\'
ru7 Russian Sanitator 2019-02-18 08:08:49 316 (сохранено в черновиках)
en12 English Sanitator 2019-02-17 19:19:24 89
ru6 Russian Sanitator 2019-02-17 19:18:38 144
en11 English Sanitator 2019-02-17 19:15:47 56
en10 English Sanitator 2019-02-17 18:07:17 4
en9 English Sanitator 2019-02-17 17:54:08 2 Tiny change: '\noutput: s: `Hello worl' -> '\noutput: `s: Hello worl'
en8 English Sanitator 2019-02-17 17:52:14 5 Tiny change: '\nDebugging ' -> 'Debugging ' (published)
en7 English Sanitator 2019-02-17 17:50:17 278 (saved to drafts)
ru5 Russian Sanitator 2019-02-17 17:32:03 1622
en6 English Sanitator 2019-02-17 16:55:03 3 Tiny change: 'n#### How my formatted' -> 'n#### How formatted'
en5 English Sanitator 2019-02-17 16:52:30 1 Tiny change: 're reached You know ' -> 're reached. You know '
en4 English Sanitator 2019-02-17 16:50:38 1982 Tiny change: 'ly. \n\n\n----------------------\nDebuggin' -> 'ly. \n\n\nDebuggin'
ru4 Russian Sanitator 2019-02-17 14:06:48 3 Мелкая правка: 'IhQ5iUeQ).\nP.P.S. Е' -> 'IhQ5iUeQ). \n\nP.P.S. Е'
en3 English Sanitator 2019-02-17 14:04:51 0 (published)
ru3 Russian Sanitator 2019-02-17 14:04:21 0 (опубликовано)
en2 English Sanitator 2019-02-17 14:03:49 0 (saved to drafts)
ru2 Russian Sanitator 2019-02-17 14:02:12 1722 (сохранено в черновиках)
en1 English Sanitator 2019-02-17 13:45:05 1502 Initial revision for English translation
ru1 Russian Sanitator 2019-02-17 12:22:11 1502 Первая редакция (опубликовано)