I need to create a series of consecutive numbers during my code at compile time. I tried "__COUNTER__" as follows:
void test1() { printf("test1(): Counter = %d\n", __COUNTER__); } void test2() { printf("test2(): Counter = %d\n", __COUNTER__); } int main() { test1(); test2(); }
And the result was perfect, as I expected:
test1(): Counter = 0 test2(): Counter = 1
Then I distribute "__COUNTER__" in different .cpp files:
In Foo.cpp: Foo::Foo() { printf("Foo::Foo() with counter = %d\n", __COUNTER__); } In Bar.cpp: Bar::Bar() { printf("Bar::Bar() with counter = %d\n", __COUNTER__); } In Main.cpp: int main() { Foo foo; Bar bar; }
The result is:
Foo::Foo() with counter = 0 Bar::Bar() with counter = 0
It seems to me that "__COUNTER__" is provided as a variable for each compilation unit .
What I would like to have is a global counter that is efficient in all code.
This is used for testing in a debug assembly where I want to achieve this goal:
Imagine I have try / catch blocks throughout the code (subsystem or module in multiple .cpp files). At run time, the program runs in a loop, inside each loop, all try blocks will be executed in orders (in which order it does not matter), and I want to check how the code responds to an exception for each attempt / catch, one at a time. For example, the first time in loop # 1 try / catch block throws an exception; second time in the loop, # 2 try / catch block throws an exception, etc. etc.
I plan to have a global counter as follows:
int g_testThrowExceptionIndex = 0;
In each try / catch:
try { TEST_THROW_EXCEPTION(__COUNTER__) //My logic is here... } catch(...) { //Log or notify... }
And the macro will be something like this:
#define TEST_THROW_EXCEPTION(n) \ if(g_testThrowExceptionIndex == n)\ {\ g_testThrowExceptionIndex++;\ throw g_testThrowExceptionIndex;\ }\
Without the ability to generate a sequence number at compile time, I have to write a macro like this:
TEST_THROW_EXCEPTION(THROW_INDEX_1) ...... TEST_THROW_EXCEPTION(THROW_INDEX_N)
And in the header is defined:
#define THROW_INDEX_1 0 #define THROW_INDEX_2 1 ......
The problem is that every time you add a try / catch block and want to test, you need to create a new constant via #define and put it in the macro. Worse, what if you remove some of the try / catch blocks from the code? You also need to update the #define list ...
===============
Solution: Thanks for the Suma idea, I ended up with something like this:
#if defined(_DEBUG) && defined(_EXCEPTION_TEST) extern int g_testThrowExceptionIndex; struct GCounter { static int counter; // used static to guarantee compile time initialization static int NewValue() {return counter++;} }; #define TEST_THROW_EXCEPTION \ static int myConst = GCounter::NewValue();\ if(g_testThrowExceptionIndex == myConst)\ {\ g_testThrowExceptionIndex++;\ throw 0;\ } #else #define TEST_THROW_EXCEPTION #endif
In main.cpp:
#if defined(_DEBUG) && defined(_EXCEPTION_TEST) int g_testThrowExceptionIndex= 0; int GCounter::counter= 0; #endif
You can then put "TEST_THROW_EXCEPTION" in any of your try / catch block that you want to check.