I'm interested to know what you think is "grody". This is what I came up with:
#define DO(...) for(long long _a[]={__VA_ARGS__,1,1,1,1},i=0;i<*_a;++i) \
for(long long j=0;j<_a[1];++j)for(long long k=0;k<_a[2];++k)
It doesn't seem bad to me, and it'd be pretty easy to extend or add asserts to catch when you introduce a fourth arg.gcc also appears smart enough to remove the unnecessary loads, so I'm going to keep playing with it.