c++ - How to enhance this variable-dumping debug macro to be variadic? -


first working code:

#include <iostream>  // note: requires compiler has __pretty_function__, gcc or clang #define dump(v) std::cerr << __pretty_function__ << ':' << __line__ << ':' << #v << "='" << (v) << "'\n"  int main(int argc) {      dump(argc);     dump(argc+1);     return 0; } 

which gives stderr output (gcc):

int main(int):8:argc='1' int main(int):9:argc+1='2' 

now i'd have variadic macro number of arguments, example

dump(argc, argc+1); work, output like:

int main(int):8:argc='1',argc+1='2'


but not yet come nice solution. possible macro? if not, how templates, or combination of macros , templates? c++11 , boost ok if needed, , solution can gcc-specific if there's no standard way. looking actual code, makes variadic dump work described above, or @ least show equivalent info.

ok. not nice. works, prespecified number of arguments (i got lazy @ 4). heavily ripped off here (seriously, click , upvote). uses trick of literally expanding arguments in front of prewritten list, pulling off correct number fixed position @ back. calls correct macro name appending number. clear? nope! here's code:

#include <iostream>  // pretty normal macro tricks  #define stringize(a) stringize1(a) #define stringize1(a) stringize2(a) #define stringize2(a) #a  #define concat(a, b)  concat1(a, b) #define concat1(a, b) concat2(a, b) #define concat2(a, b) a##b  // faux-recursively dump arguments  #define dump_1(first) std::cout << stringize(first) << "='" << first << "'\n";  #define dump_2(first, ...) \ {\     std::cout << stringize(first) << "='" << first << "': ";\     dump_1(__va_args__);\ } while (false)  #define dump_3(first, ...) \ {\     std::cout << stringize(first) << "='" << first << "': ";\     dump_2(__va_args__);\ } while (false)  #define dump_4(first, ...) \ {\     std::cout << stringize(first) << "='" << first << "': ";\     dump_3(__va_args__);\ } while (false)   // count arguments  // construct forward/backward list: #define count_args(...)  count_args_(__va_args__, rseq()) // forward list on (macro pain): #define count_args_(...) count_args_n(__va_args__) // n+1th element count (predetermined support n) #define count_args_n(_1, _2, _3, _4, n, ...) n #define rseq() 4, 3, 2, 1   // calls correct dump_# #define dump_(n, ...) concat(dump_, n)(__va_args__) // start line, , start "recursion" #define dump(...) \ {\     std::cout << __pretty_function__ << ':' << __line__ << ": "; \     dump_(count_args(__va_args__), __va_args__); \ } while (false)  int main(int argc, char* argv[]) {     dump(argc);      int = 10;     const char str[] = "hello, world";     dump(i, str);      return 0; } 

output:

$ ./a.out  int main(int, char**):49: argc='1' int main(int, char**):52: i='10': str='hello, world' 

edit: here's simple version of counting part (the hard part):

#include <iostream>  #define count_args(...)  count_args_(__va_args__, rseq()) #define count_args_(...) count_args_n(__va_args__) #define count_args_n(_1, _2, _3, _4, _5, _6, n, ...) n #define rseq() 6, 5, 4, 3, 2, 1  int main() {     std::cout << count_args(a, b) << '\n';     std::cout << count_args(a, b, c, d) << '\n';      return 0; } 

output:

1 2 

how work?

well set count 6, have. constructs long list, , pulls off 7th element. contains correct value, because list pulls value constructed putting arguments user gave, followed count in reverse.

so adding argument, push backwards count along 1, , higher number it. @ picture: enter image description here


Comments

Popular posts from this blog

linux - xterm copying to CLIPBOARD using copy-selection causes automatic updating of CLIPBOARD upon mouse selection -

c++ - qgraphicsview horizontal scrolling always has a vertical delta -