This is clearly undefined because the ads do not match. As you noted, const int and int are not compatible types. Diagnostics is only required if they are displayed in one area.
In practice, this is unsafe, consider
$ cat test1.c #include <stdio.h> extern const int n; void foo(void); int main(void) { printf("%d\n", n); foo(); printf("%d\n", n); } $ cat test2.c int n; void foo(void) { ++n; } $ gcc -std=c99 -pedantic test1.c test2.c && ./a.out 0 1 $ gcc -O1 -std=c99 -pedantic test1.c test2.c && ./a.out 0 0
Gcc assumes that n does not change with foo() during optimization, since it can assume that the definition of n is of a compatible type, thus const .
You will most likely get the expected behavior with volatile -qualifying n in test1.c , but as for the C standard, it is still undefined.
The best way I can prevent the user n from being accidentally modified is to point to a pointer to const , something like
int my_real_variable; const int *const my_variable = &my_real_variable;
or maybe a macro
#define my_variable (*(const int *)&my_variable)
With C99, my_real_variable can be avoided through a compound literal:
const int *const my_variable_ptr = &(int){ 12 };
It would be legal to discard const here (since the int object itself is not const ), but the cast was necessary, preventing accidental modification.
mafso source share