For example, can I do something like this so that only foo.c
can modify the variable 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;
}
And so that the following would produce an 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;
}
Is this guaranteed to link correctly?
Can I declare a variable as const in the public header and not in the private header?
No, you cannot as it invokes undefined behavior.
(C11, 6.2.7p2) "All declarations that refer to the same object or function shall have compatible type; otherwise, the behavior is undefined."
const int
and int
are two type incompatible types.
(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"
No. If the declarations mismatch, the behavior of the program is undefined. In particular, since the translation units using the public header are declaring that the object is const
qualified, the compiler can, when translating them, make an assumption that the pointed-to data will never change, so it could cache the value across calls to external functions, including the functions that change it.
If you just want protection against accidentally writing code that tries to modify the data, do this:
extern int foo;
#define foo (*(const int *)&foo)
Then you can #undef foo
in the modules that are actually permitted to change it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With