2010-03-31 29 views
9

Mientras que suena sin sentido .....¿Se puede hacer un compilador incremental constante?

Quiero una constante en el que cada vez que lo utilice se aumentará en 1

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

donde x == 1; y y == 2

Nota No quiero y = INCREMENTING_CONSTANT + 1 soluciones de tipo.

Básicamente quiero utilizarlo como un ID único tiempo de compilación (por lo general no se utiliza en código como el ejemplo, pero dentro de otra macro)

+0

Dado que la variable se basa en el compilador, necesitamos saber de qué compilador está hablando. –

+0

compilador cruzado ... idealmente como se usará en al menos 3 compiladores. –

+0

esto realmente duplica http://stackoverflow.com/questions/2076757/incremented-define pero las soluciones son para C++, pero veré si las mismas técnicas se pueden usar para C –

Respuesta

-1

Bueno, no es constante, entonces, ¿verdad? ;)

Usted puede 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 hacer eso, necesitaría proteger esto con un mutex, o usar un compilador/incrementador atómico específico de la plataforma.

+0

, compile la constante de tiempo :) que es donde su respuesta es totalmente ¡falla! :) por lo tanto, mi pregunta, ¿cómo hacer un incremento en la constante de compilación de tiempo! al igual que ____LINE____ cambia dependiendo de la línea de código en la que se encuentre :) –

+1

No creo que esto sea exactamente lo que él quiere. Esto generará un nuevo valor en tiempo de ejecución cada vez que se llame a la función. Creo que quiere que el valor se calcule una vez en el momento de la compilación, luego se usa el mismo valor cada vez que se ejecuta esa línea. –

-2

Una "constante creciente" es un oxímoron. No puedes hacer esto en tiempo de compilación.

+2

parece uno, pero la parte "constante" se refiere a ser constante en tiempo de compilación en lugar de ser el símbolo. –

+2

En realidad son muchos valores constantes, cada uno mayor que el anterior –

7

Usted puede ser capaz de poner algo juntos usando Boost.Preprocessor (Funciona con C) y BOOST_PP_COUNTER

ejemplo dado en la página docs:

#include <boost/preprocessor/slot/counter.hpp> 
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 al lo que quiere

#include <boost/preprocessor/slot/counter.hpp> 

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 podría usar ranuras (un poco más flexible a cambio de más código que la solución anterior):

#include <boost/preprocessor/slot/slot.hpp> 

#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 
6

Si sólo necesita algo único ID ish, se puede utilizar el símbolo __LINE__ preprocesador? No es lo que estás pidiendo, pero podría funcionar para tus propósitos.

+0

De acuerdo, siempre uso '__LINE__' para el mismo tipo de cosas que veo '__COUNTER__' usado. –

+0

__LINE__ Es lo que quiero dejar de usar –

1

A menudo he deseado variables de tiempo de compilación. Sin embargo, lo más fácil sería simplemente definir constantes para cada uno de forma individual.

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

También podría intentar usar un xmacro. Crear un nuevo archivo, vamos a llamarlo 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 xmacros tienen un poder increíble que las macros regulares puede' uso, como defs/undefs, y mi intuición dice que debería funcionar. El preprocesador es poderoso, pero bastante tonto, por lo que podría fallar.

+0

esto parece prometedor .... –

+2

Esto no funcionará - el preprocesador no ve las directivas que resultan de la expansión de macros. – caf

0

¿Desea que x y y sean constantes? Si es así lo más fácil y más limpio que hacer puede ser utilizar una enumeración anónima:

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

Esto significa que sólo tiene que añadir un nuevo nombre a la lista y se les dará el siguiente valor entero. Este es un truco útil en el que no importa cuáles sean los valores (fuera del tiempo de ejecución), siempre que sean distintos. Por ejemplo, al asignar identificadores a los controles en una interfaz gráfica de usuario, que suelen aparecer:

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

Algunos marcos de interfaz gráfica de usuario proporcionan una función getUserId() que va a 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 consecutivas.

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

lamentablemente no, no puedo usar la cosa enum, es completamente desconocido cuántos elementos puede haber. –

+0

No estoy seguro de por qué eso es un problema. ¿Por qué es más difícil agregar un nuevo elemento a una enumeración de lo que es (por ejemplo) agregar otra línea de código para inicializarlo en alguna constante, en otro lugar? – Edmund

+0

porque la macro puede aparecer en cualquier punto del código. Lo más probable es que esté en el cuerpo de una función ...y otra macro estaría en el cuerpo de otra función, etc., habrá una cantidad arbitraria de referencias a la macro en muchas funciones diferentes. Cada vez que aparece la macro, quiero que incremente en 1 –

-3

Aquí hay una manera fea de implementarlo.

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

nuevamente, esto no es una constante de tiempo de compilación, su tiempo de ejecución ... –

2

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

Esto es lo que me ocurrió hace un momento:

#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 reto será asegurarse de que los incluya la cadena que lleva en cada uno de estos bloques se compila en el mismo orden cada vez.

Cuestiones relacionadas