Necesito generar una serie de números secuenciales en todo mi código en tiempo de compilación. Probé "__COUNTER__" de una manera como esto:Instalación del preprocesador __COUNTER__ en Visual C++
void test1()
{
printf("test1(): Counter = %d\n", __COUNTER__);
}
void test2()
{
printf("test2(): Counter = %d\n", __COUNTER__);
}
int main()
{
test1();
test2();
}
y el resultado fue perfecto, ya que esperaba:
test1(): Counter = 0
test2(): Counter = 1
Entonces extendí "__COUNTER__" en diferentes archivos .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;
}
El resultado fue:
Foo::Foo() with counter = 0
Bar::Bar() with counter = 0
Me parece que "__COUNTER__" se proporciona como por unidad de compilación variable.
Lo que me gustaría tener es un contador global que sea efectivo en todo el código.
Esto se utiliza para realizar pruebas en una versión de depuración donde quiero lograr este objetivo:
Imagínese que tengo bloques try/catch en todo el código (un subsistema o un módulo dentro de varios archivos .cpp). En tiempo de ejecución, el programa se ejecuta en un ciclo, dentro de cada ciclo todos los bloques de prueba se ejecutarán en órdenes (en cuyo orden no importa), y quiero probar cómo reacciona el código a la excepción para cada intento/captura, uno a uno. Por ejemplo, la primera vez en el ciclo, el bloque # 1 try/catch arroja una excepción; por segunda vez en el bucle, # 2 Bloque try/catch se produce una excepción, etc, etc
planeo tener un contador global de esta manera:
int g_testThrowExceptionIndex = 0;
En cada try/catch:
try
{
TEST_THROW_EXCEPTION(__COUNTER__)
//My logic is here...
}
catch(...)
{
//Log or notify...
}
y la macro sería algo como esto:
#define TEST_THROW_EXCEPTION(n) \
if(g_testThrowExceptionIndex == n)\
{\
g_testThrowExceptionIndex++;\
throw g_testThrowExceptionIndex;\
}\
Sin la capacidad de generar el número de secuencia de una t tiempo de compilación, tengo que escribir la macro como esta:
TEST_THROW_EXCEPTION(THROW_INDEX_1)
......
TEST_THROW_EXCEPTION(THROW_INDEX_N)
Y en la cabecera, define:
#define THROW_INDEX_1 0
#define THROW_INDEX_2 1
......
El problema es que cada vez que añada un bloque try/catch y desea para probar, tienes que crear una nueva constante a través de #define y poner ese número en la Macro. Peor aún, ¿qué sucede si elimina algunos de los bloques try/catch del código? Usted tiene que actualizar su lista #define también ...
==============
Solución: Gracias por la idea de Suma, que terminaron con algo como esto:
#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
en main.cpp:
#if defined(_DEBUG) && defined(_EXCEPTION_TEST)
int g_testThrowExceptionIndex= 0;
int GCounter::counter= 0;
#endif
entonces usted puede poner "TEST_THROW_EXCEPTION" en cualquiera de su bloque try/catch que desea probar.
Con los archivos de encabezado precompilados, '__COUNTER__' dentro de esos causa aún más problemas. La solución +1 de Suma es muy portátil y evita problemas de preprocesamiento. – wallyk
Eso funciona, hace exactamente lo que quiero hacer. ¡Gracias! – Ping