Declarar una variable global `extern const int` en el encabezado pero solo` int` en el archivo fuente

Estaba experimentando con GCC y descubrí que puede declarar const variables externas en los archivos de cabecera, pero mantenerlas mutables en los archivos de implementación.

EDIT : Esto en realidad no funciona. La única razón por la que compilé mi código de prueba fue porque no incluí “header.h” en “header.c”.

header.h:

 #ifndef HEADER_H_ #define HEADER_H_ extern const int global_variable; #endif 

header.c:

 int global_variable = 17; 

Esta parece ser una muy buena característica que se debe usar para mantener la global_variable solo para los usuarios de header.h pero para que sean modificables por la implementación ( header.c ).

NOTA: El siguiente código es solo un ejemplo de cómo esta forma de statement evitará la asignación a global_variable .

 #include "header.h" int main(void) { global_variable = 34; /* This is an error as `global_variable` is declared const */ return 0; } 

Porque nunca antes había visto la técnica en la práctica. Empiezo a preguntarme si es válido.

¿Está esto bien definido, o es un error del que GCC no me advierte?

const int e int no son tipos compatibles.

Por ejemplo esto:

 extern const int a; int a = 2; 

no es válido en C como C dice que:

(C11, 6.7p4) “Todas las declaraciones en el mismo ámbito que se refieren al mismo objeto o función deben especificar tipos compatibles”

En su caso, no están en el mismo ámbito (diferentes unidades de traducción) pero C también dice que:

(C11, 6.2.7p2) “Todas las declaraciones que se refieran al mismo objeto o función tendrán un tipo compatible; de ​​lo contrario, el comportamiento no está definido”.

Como estás violando la regla anterior, estás invocando un comportamiento indefinido.

Tenga en cuenta que C90 tiene los mismos párrafos.

Un poco tarde, pero de todos modos.

Creo que esto puede funcionar si haces algo como esto.

en header.h:

 #ifndef HEADER_H_ #define HEADER_H_ #ifndef HAS_GLOB_VAR extern const int global_variable; #endif #endif 

y si necesita incluir el encabezado en el archivo que realmente define la variable ( header.c ), haga algo como

 #define HAS_GLOB_VAR #include "header.h" int global_variable = 17; ... 

En los otros archivos, solo incluye el encabezado y no define HAS_GLOB_VAR .

No está asignando un valor a global_variable, lo está definiendo.