Mat*_*att 4 c linker const header-files
例如,我可以做这样的事情,以便只能foo.c修改变量foo吗?:
foo.h:
extern const int foo;
void foo_init(void);
void foo_reinit(void);
Run Code Online (Sandbox Code Playgroud)
foo.private.h:
int foo;
void foo_init(void);
void foo_reinit(void);
Run Code Online (Sandbox Code Playgroud)
foo.c:
#include "foo.private.h"
void foo_init() { foo = 1; /* ... */ }
void foo_reinit() { foo++; /* ... */ }
Run Code Online (Sandbox Code Playgroud)
bar.c:
#include <foo.h>
int main()
{
foo_init(); printf("foo: %d\n", foo);
foo_reinit(); printf("foo: %d\n", foo);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
因此,以下将产生错误/警告:
baz.c:
#include <foo.h>
int main()
{
foo_init(); printf("foo: %d\n", foo);
foo = 0; /* ERROR/WARNING for modifying const variable */
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这保证正确链接吗?
不可以.如果声明不匹配,程序的行为是不确定的.特别是,由于使用公共头的翻译单元声明对象是const合格的,编译器在翻译它们时可以假设指向的数据永远不会改变,因此它可以将值缓存到外部调用功能,包括改变它的功能.
如果您只是想要防止意外编写试图修改数据的代码,请执行以下操作:
extern int foo;
#define foo (*(const int *)&foo)
Run Code Online (Sandbox Code Playgroud)
然后,您可以#undef foo在实际允许更改它的模块中.
我可以在公共标头中而不是在私有标头中将变量声明为const吗?
不,你不能因为它调用未定义的行为.
(C11,6.2.7p2)"所有引用相同对象或函数的声明都应具有兼容类型;否则,行为未定义."
const int并且int是两种类型不兼容的类型.
(C11,6.7.3p10)"对于两个要兼容的限定类型,两者都应具有相同类型的兼容类型;说明符或限定符列表中类型限定符的顺序不会影响指定的类型"