2012-05-21 19 views
5

¿Esto es posible?Posible inicializar la variable estática llamando a la función

static bool initialize() 
{ 
    TRC_SCOPE_INIT(...); 
    ... 
} 

static bool initialized = initialize(); 

Para hacer una larga historia corta, tengo que llamar a una serie de macros (para inicializar los mensajes de depuración) tan pronto como sea posible (antes de que se inicie el hilo X, y que no tienen la capacidad de saber cuando se inicia el hilo X).

+1

¿Puedes insertar una llamada a 'pthread_once (3)' en tu rutina 'main()'? – sarnold

+0

@KingsIndian: 'bool' es válido en C99 con el encabezado' stdbool.h'. – icktoofay

+0

@icktoofay No se especificó como c99 de todos modos, por lo que se agregó la etiqueta C++. –

Respuesta

6

Cuando originalmente miré la pregunta, estaba etiquetada tanto en C como en C++. El código podría ser C o C++ porque bool es un tipo en C99 y C11, igual que en C++ (casi; en C, necesita el encabezado <stdbool.h> para obtener el nombre bool).

Las respuestas para las dos etiquetas son:

  • En C++, sí.

  • En C, no.

No son del mismo idioma. Si necesita una demostración, este es un buen ejemplo como cualquier otro.

+2

La pregunta fue etiquetada solo como 'c' cuando se publicó originalmente. @KingsIndian agregó la etiqueta 'C++' debido al 'bool', pero revertí esa edición porque' bool' es válido en C99 y no hubo ninguna indicación de la publicación original de que estuviera relacionado con C++. – icktoofay

+0

@icktoofay: gracias por la aclaración; Ajusté mi respuesta ligeramente para reconocer los cambios. –

+0

para aquellos que son curiosos, (a) C++ 11 le permite usar constexpr, (b) hay sorprendentemente poca compatibilidad con el compilador –

1

Esto debería estar bien siempre que las "cosas" que está inicializando estén definidas en la misma unidad de traducción que la llamada a la función que lo inicializa. Además, debe estar definido encima del sitio de llamadas. De lo contrario, corre el riesgo de un comportamiento indefinido debido al uso de valores no inicializados.

Una forma de evitar esto es utilizar un puntero en su lugar. Un puntero inicializado estáticamente se compila en la imagen ejecutable, por lo que no hay riesgo de un comportamiento indefinido si es utilizado por statics definidos en otras unidades de traducción. En su función de inicialización estática asigna dinámicamente las "cosas" y establece el puntero para que apunte a él para que pueda acceder a él más tarde.

4

Si está utilizando GCC (o sonido metálico), puede utilizar __attribute__((constructor)):

static bool initialized = false; 

__attribute__((constructor)) 
static void initialize(void) { 
    initialized = true; 
    // do some other initialization 
} 

int main(int argc, char **argv) { 
    // initialize will have been run before main started 
    return 0; 
} 
1

(Ya que menciona hilos, voy a asumir que tiene funciones de hilos POSIX a su disposición.)

La función pthread_once existe para este propósito. En cualquier lugar que necesita estar seguro de initialize ya se ha dado en llamar, escribir:

pthread_once(&init_once, initialize); 

donde init_once se define con una duración de almacenamiento estático, y posiblemente con enlace externo si es necesario, como pthread_once_t init_once.

Cuestiones relacionadas