¿Puedes hacer una constante comstackdor creciente?

Mientras suena sin sentido …..

Quiero una constante donde cada vez que la uses se incrementará en 1

int x; int y; x = INCREMENTING_CONSTANT; y = INCREMENTING_CONSTANT; 

donde x == 1; y y == 2

Tenga en cuenta que no quiero y = INCREMENTING_CONSTANT + 1 soluciones tipo.

Básicamente, quiero usarlo como un ID único de tiempo de comstackción (generalmente no se usará en código como el ejemplo pero dentro de otra macro)

No es estándar, pero algunos comstackdores admiten la macro __COUNTER__ . Consulte ¿Alguien ha tenido alguna vez un uso para la macro preprocesador __COUNTER__?

Es posible que pueda armar algo usando Boost.Preprocessor (Funciona con C) y BOOST_PP_COUNTER

Ejemplo dado en la página de documentos :

 #include  BOOST_PP_COUNTER // 0 #include BOOST_PP_UPDATE_COUNTER() BOOST_PP_COUNTER // 1 #include BOOST_PP_UPDATE_COUNTER() BOOST_PP_COUNTER // 2 #include BOOST_PP_UPDATE_COUNTER() BOOST_PP_COUNTER // 3 

Traducido a lo que quieras

 #include  int x = BOOST_PP_COUNTER; // 0 #include BOOST_PP_UPDATE_COUNTER() int y = BOOST_PP_COUNTER;// 1 #include BOOST_PP_UPDATE_COUNTER() int z = BOOST_PP_COUNTER; // 2 

También puede usar ranuras (un poco más flexible al costo de más código que la solución anterior):

 #include  #define BOOST_PP_VALUE 0 //ensure 0 to start #include BOOST_PP_ASSIGN_SLOT(1) int a = BOOST_PP_SLOT(1); //0 #define BOOST_PP_VALUE 1 + BOOST_PP_SLOT(1) #include BOOST_PP_ASSIGN_SLOT(1) int b = BOOST_PP_SLOT(1); //1 

Si solo necesita una ID de identificación única, ¿puede usar el símbolo del preprocesador __LINE__ ? No es lo que estás pidiendo, pero podría funcionar para tus propósitos.

En mi caso, quería tener una clave única de todo el sistema para cada subsistema, pero la selección de los subsistemas dependería de la persona que utilice el sistema. Estos debían ser valores de 8 bits porque están dirigidos a sistemas integrados.

Esto es lo que se me ocurrió justo ahora:

 #define LAST_KEY -1 // SUB1_KEY definition enum { SUB1_KEY_ORIGIN = LAST_KEY, SUB1_KEY, }; #undef LAST_KEY #define LAST_KEY SUB1_KEY // SUB2_KEY definition enum { SUB2_KEY_ORIGIN = LAST_KEY, SUB2_KEY, }; #undef LAST_KEY #define LAST_KEY SUB2_KEY // SUB3_KEY definition enum { SUB3_KEY_ORIGIN = LAST_KEY, SUB3_KEY, }; #undef LAST_KEY #define LAST_KEY SUB3_KEY // .... 

El desafío será asegurarse de que la cadena de inclusión que trae cada uno de estos bloques se compile en el mismo orden cada vez.

A menudo he deseado variables de tiempo de comstackción. Sin embargo, lo más fácil sería simplemente definir las constantes para cada una de manera no válida.

La respuesta sobre el problema del subproceso de mí podría resolverse mediante el uso de un functionoid en alguna clase de estado global o un tipo de solución similar si está utilizando C en lugar de C ++.

También puedes intentar usar un xmacro. Crea un nuevo archivo, llamémoslo xmacro.h

 INCREMENTING_CONSTANT; #define INCREMENTING_CONSTANT INCREMENTING_CONSTANT + 1 

Luego, en un encabezado estándar,

 #define INCREMENTING_CONSTANT 0 #define USE_INCREMENTING_CONSTANT #include "xmacro.h" const int x = USE_INCREMENTING_CONSTANT 

No he probado esto, pero los xmacros tienen un poder increíble que las macros normales no pueden usar, como defs / undefs, y mi instinto dice que debería funcionar. El preprocesador es poderoso, pero bastante tonto, por lo que podría fallar.

Bueno, entonces no es constante, ¿verdad? 😉

Puedes hacer esto con una función:

 int id() { static int i = 0; return ++i; } x = id(); y = id(); 

Como se muestra, esto no es seguro para subprocesos. Para hacerlo, debería proteger esto con una exclusión mutua o usar un incrementador atómico específico de la comstackción / plataforma.

¿Quieres que x sean constantes en sí mismas? Si es así, lo más fácil y limpio es usar una enumeración anónima:

 enum { x = 1, y /* Add new ones here. */ }; 

Esto significa que solo necesita agregar un nuevo nombre a esa lista y se le dará el siguiente valor entero. Este es un truco útil en el que no le importa cuáles son los valores (fuera del tiempo de ejecución), siempre que sean distintos. Por ejemplo, al asignar identificadores a los controles en una GUI, a menudo se ve:

 enum { button1_id = FIRST_USER_ID, button2_id, combo_id, ... } 

Algunos marcos de la GUI proporcionan una función GetUserId () que generará una nueva (utilizando una variable estática interna); Pero creo que esto sucede en tiempo de ejecución. También es un poco tedioso ver tantas llamadas sucesivas.

 button1_id = GetUserId(); button2_id = GetUserId(); combo_id = GetUserId(); ... 

Una “constante incrementadora” es un oxímoron. No puedes hacer esto en tiempo de comstackción.

Aquí hay una manera fea de implementarlo.

 static int _counter=0; #define INCREMENTING_CONSTANT (_counter++)