我可以在 public header 中而不是在私有 header 中将变量声明为 const 吗?

Can I declare a variable as const in the public header and not in the private header?

例如,我可以做这样的事情,只有foo.c可以修改变量foo吗?:

foo.h:

extern const int foo;
void foo_init(void);
void foo_reinit(void);

foo.private.h:

int foo;
void foo_init(void);
void foo_reinit(void);

foo.c:

#include "foo.private.h"
void foo_init() { foo = 1; /* ... */ }
void foo_reinit() { foo++; /* ... */ }

bar.c:

#include <foo.h>
int main()
{
    foo_init(); printf("foo: %d\n", foo);
    foo_reinit(); printf("foo: %d\n", foo);
    return 0;
}

这样下面的语句就会产生一个 error/warning:

baz.c:

#include <foo.h>
int main()
{
    foo_init(); printf("foo: %d\n", foo);
    foo = 0; /* ERROR/WARNING for modifying const variable */
    return 0;
}

这保证 link 正确吗?

你喜欢踩多薄的冰?

是的,你可以做到。你会侥幸逃脱的。但该标准并不能保证您的代码会按预期工作。相同的 object 应在所有地方一致声明。

但是主要的问题是你失去了你应该需要的 cross-checking 因为你的 'private' 代码应该使用 public header 来确保声明外部使用匹配实现。也就是说,foo.c 应该有 #include "foo.h" 以确保告知消费者使用的内容与实现提供的内容相匹配(在 foo.c 中)。如果你不这样做,事情迟早会出问题。

此外,请记住编译器讨厌被骗。当你对他们撒谎时,他们会想办法报复他们。你的代码对编译器说谎了。

没有。如果声明不匹配,则程序的行为是未定义的。特别是,由于使用 public header 的翻译单元声明 object 是 const 合格的,编译器在翻译它们时可以假设 object =19=] 数据永远不会改变,所以它可以在调用外部函数时缓存值,包括改变它的函数。

如果您只想防止意外编写试图修改数据的代码,请执行以下操作:

extern int foo;
#define foo (*(const int *)&foo)

那你可以#undef foo在实际允许的模块里改

我可以在 public header 而不是在私有 header 中将变量声明为 const 吗?

不,你不能,因为它会调用未定义的行为。

(C11, 6.2.7p2) "All declarations that refer to the same object or function shall have compatible type; otherwise, the behavior is undefined."

const intint 是两种类型不兼容的类型。

(C11, 6.7.3p10) "For two qualified types to be compatible, both shall have the identically qualified version of a compatible type; the order of type qualifiers within a list of specifiers or qualifiers does not affect the specified type"

不,你不能,但据我了解你的代码,你可以将 foo 设为静态,作为函数 foo_initfoo_reinit,并公开一个简单的 get_foo到其他模块。