Мне нужно сгенерировать последовательность последовательных чисел во всем коде во время компиляции.Я попробовал «__COUNTER__» таким образом:
void test1()
{
printf("test1(): Counter = %d\n", __COUNTER__);
}
void test2()
{
printf("test2(): Counter = %d\n", __COUNTER__);
}
int main()
{
test1();
test2();
}
И результат был идеальным, как я и ожидал:
test1(): Counter = 0
test2(): Counter = 1
Затем я разложил «__COUNTER__» в разные файлы .cpp:
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;
}
Результат был:
Foo::Foo() with counter = 0
Bar::Bar() with counter = 0
Мне кажется, что "__COUNTER__" предоставляется как на единицу компиляции переменная.
Мне бы хотелось иметь глобальный счетчик, работающий во всем коде.
Он используется для тестирования в отладочной сборке, где я хочу достичь этой цели:
Представьте себе, чтоУ меня есть блоки try / catch по всему коду (подсистема или модуль в нескольких файлах .cpp).Во время выполнения программа работает в цикле, в каждом цикле все блоки try будут выполняться в порядке (в каком порядке это не имеет значения), и я хочу проверить, как код реагирует на исключение для каждого try / catch,по одному.Например, первый раз в цикле блок # 1 try / catch генерирует исключение;второй раз в цикле, блок try / catch # 2 генерирует исключение и т. д. и т. д.
Я планирую использовать глобальный счетчик, например:
int g_testThrowExceptionIndex = 0;
В каждом try / catch
try
{
TEST_THROW_EXCEPTION(__COUNTER__)
//My logic is here...
}
catch(...)
{
//Log or notify...
}
И макрос мог бы выглядеть примерно так:
#define TEST_THROW_EXCEPTION(n) \
if(g_testThrowExceptionIndex == n)\
{\
g_testThrowExceptionIndex++;\
throw g_testThrowExceptionIndex;\
}\
Без возможности генерировать порядковый номер во время компиляции, я должен написать макрос так:
TEST_THROW_EXCEPTION(THROW_INDEX_1)
......
TEST_THROW_EXCEPTION(THROW_INDEX_N)
И в заголовке определяет:
#define THROW_INDEX_1 0
#define THROW_INDEX_2 1
......
Проблема в том, что каждый раз, когда вы добавляете блок try / catch и хотите протестировать, вы должны создать новую константу через# определить и поместить этот номер в макрос.Хуже того, что если вы удалите некоторые блоки try / catch из кода?Вы также должны обновить свой список #define ...
==============
Решение: Спасибо за идею Сумы, я кое-что закончилкак это:
#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
В main.cpp:
#if defined(_DEBUG) && defined(_EXCEPTION_TEST)
int g_testThrowExceptionIndex= 0;
int GCounter::counter= 0;
#endif
Затем вы можете поместить "TEST_THROW_EXCEPTION" в любой из ваших блоков try / catch, которые вы хотите протестировать.