tags:

views:

239

answers:

5

I'm basically looking for a way to automate typing stuff like the following:

cout << "a[" << x << "][" << y << "] =\t" << a[x][y] << endl;

Something like:

PRINTDBG(a[x][y]);

Ideally this would also work for

PRINTDBG(func(arg1, arg2));

and even

PRINTDBG(if(condition) func(foo););

(which would print e.g. "if(false) func(5)").

Nonportable hacks welcome too :)

(no, using a debugger isn't the same, it's much less flexible and I find it confusing)

+2  A: 

This is an area where the printf style output can be more concise:

cout << "a[" << x << "][" << y << "] =\t" << a[x][y] << endl;
printf("a[%d][%d] =\t%d\n", x, y, a[x][y]);

Of course, this has the limitation of only working for types that printf understands, and it still doesn't address your question.

I get the feeling that there might be something of value in the expression decomposition techniques in Boost, but I am not enough of a template ninja to identify what.

Update: The following almost addresses your question:

#define PRINTDBG(x) cout << #x << " =\t" << x << endl;

However, when used as PRINTDBG(a[x][y]) it literally prints:

a[x][y] = 5

which doesn't give the actual values of x and y.

Greg Hewgill
+2  A: 

This is, in the way you want it, not possible. If you have if(condition) func(foo); given to a macro, it can stringize that stuff, and it will print if(condition) func(foo);, but not with the actual values of the variables substituted. Remember the preprocessor doesn't know about the structure about that code.

For debugging, i would use some type-safe printf variant like boost.format or some home brew printf with boost.fusion, which make the job of printing stuff like that much more easy:

dprintf("a[%][%] = %", (x, y, a[x][y]));
Johannes Schaub - litb
this _is_ less painful than both cout and printf, cheers :)
thanks. i hope you enjoy it. if you are worried about performance (it's around 300ms slow for 1000000 iterations, while printf takes only 40ms), you can use this optimized version for char*: http://codepad.org/8ZQvdoMq . it collects chars, and writes them in one go. takes only 70ms then :)
Johannes Schaub - litb
it additionally uses a struct, for avoiding passing the end iterator all again, just to pass over the type of it. but here, it's just a game since you use it for debug, time doesn't matter anyway. but maybe you decide to use it for other stuff too. have fun :)
Johannes Schaub - litb
A: 
Tree77
A: 

In a slight expansion in a different direction to Greg's posting, I've seen some nice C programs that look something like this

#DEFINE DEBUG_MODE 1
//...
if( DEBUG_MODE)
  printf("methodX() says: y=%i, var1=%i", y, var1);

However you still have a ton of printf's in your program, but at least you can turn them all on and off when you want to.

rlb.usa
A: 

you can define operator« for custom classes so you only have to define formatting once:

struct point3 {
      int x,y,z;
      point3(int a, int b, int c){x=a;y=b;z=c;}
};

std::ostream& operator << (std::ostream& os, const point3& f) {
      return os << "(" << f.x << "," << f.y << "," << f.z << ")";
}

point3 p(1,2,3);
std::cout << p; // prints "(1,2,3)"

this pairs well with redirecting cout or clog to a file (don't recall how std::clog works)

#include <iostream>
#include <fstream>

int main() {
      std::ofstream file("log.txt");
      std::streambuf *filebuf = file.rdbuf();
      std::cout.rdbuf(filebuf);

      std::cout << "This is written to the file";

      filestr.close();
      return 0;
}
Dustin Getz
http://www.gamedev.net/community/forums/topic.asp?topic_id=426065
Dustin Getz