C 声明非常量变量&x27;合法吗;常数';外部?

C 声明非常量变量&x27;合法吗;常数';外部?,c,linker,constants,C,Linker,Constants,假设我有一个文件window.h,它定义: extern const int window_width, window_height; 我不希望任何人更改这些变量,所以它们是window.h的所有includers的常量。但是,在源文件中声明它们为非常量是否合法 // window.c int window_width, window_height; void onResizeWindow(int w, int h) { window_width = w; window_he

假设我有一个文件window.h,它定义:

extern const int window_width, window_height;
我不希望任何人更改这些变量,所以它们是window.h的所有includers的常量。但是,在源文件中声明它们为非常量是否合法

// window.c
int window_width, window_height;

void onResizeWindow(int w, int h) {
    window_width = w;
    window_height = h;
}

在Apple clang 12.0.0版(clang-1200.0.22.7)中,我编译时没有链接器错误。但这是合法且定义明确的行为吗?不,这是未定义的行为。同一对象的两个声明必须具有兼容的类型,非限定的const-类型与同一类型的限定的const-版本不兼容。(与涉及两个或多个翻译单元的其他问题一样,这种未定义的行为不需要诊断。但没有诊断消息并不意味着它正常。它只是意味着编译器一次只查看一个翻译单元,因此不会看到不一致。)


使用指向
const
限定类型的指针访问该类型的非
const
对象,甚至使用指向非
const
限定类型的指针从
const
限定对象中读取(但不变异)都不是错误。但是请注意,只要变量的实际定义不是限定的
const
,那么从指针中“丢弃
const
”并使用它来修改变量也不是一个错误。

我没有给出答案,因为我不确定标准说了什么,但我不这么认为。编译器可能会假设这些变量在初始化后不会被修改,而实际上它们是可以修改的。另外,最好只编写
int-getWindowWidth()
int-getWindowHeight()
函数,而不是公开“const”变量。