4 ms·
Without `static`, compiler exports a symbol. $ cat value.c int value = 42; int get_value() { return value; } $ make value.o
by GlitchMr 5y ago
Without `static`, compiler exports a symbol.
$ cat value.c
int value = 42;
int get_value() {
return value;
}
$ make value.o
gcc -c -o value.o value.c
$ nm value.o
0000000000000000 T get_value
U _GLOBAL_OFFSET_TABLE_
0000000000000000 D value
This symbol, not being `const` can be modified by any other compilation unit.
$ cat main.c
#include <stdio.h>
int value;
int get_value();
int main() {
value = 123456789;
printf("%d\n", get_value());
}
$ make main.o
gcc -c -o main.o main.c
$ cc value.o main.o
$ ./a.out
123456789
Compiler when generating an object file has to assume the value of exported non-const symbol can change. It's necessary to tell the compiler that the value cannot change, either by not exporting the symbol by using `static` or making the value of it `const`. In example provided in your article `static` makes sense (or even `static const`) as I don't think there is a reason to export this global.
- rostayob 5y agoYes, see last few paragraphs of the post, in which I also speculate why GCC doesn't infer that there is only one compilation unit.
- pjmlp 5y agoHow could it ever infer it, given C's compilation model? The only option is when all TU are given at the same time to the compiler, or when LTO is used (in which case it is actually the linker doing the work). Even then, this won't apply to libraries.
- rostayob 5y ago> The only option is when all TU are given at the same time to the compiler Exactly -- which is the case here. But implementing such a cross cutting implementation would probably be annoying, which is what I wanted to convey with > I think they could concievably assume that the value of modulus won’t be changed in this case, since we’re producing an executable directly, but it’s probably annoying to have an optimization looking so far into the future of the compiler pipeline.
- makapuf 5y agoI quite like C syntax, and I sometimes long for a language that would change a few elements (default to const and static, different/safer standard api for strings). Some might call it Go but a simple slightly updated C would be nice.
- mhh__ 5y agoThat is pretty much D (assuming you only want to use the C-like bits) - it's not const by default but const is much easier to use and much more violent And arrays are bounds checked by default, no more issues with them (and strings are arrays)
- nicoburns 5y agoHave you seen zig? It's a modern language that tries to keep the simplicity and explicitness of C (it does change the syntax a bit though).
- gpanders 5y agoI really wish Zig had followed Rust’s lead and made variables const by default :/
- samsin 5y agoVariables are immutable by default in Rust, but they're not const by default. The difference is that a variable can become mutable while a const is always immutable.
- makapuf 5y agoHow do you set a variable as mutable after the fact in rust?
- nicoburns 5y agoYou can do: let foo = "1234".to_string(); let mut foo = foo; foo = "5678"; This only works if you have ownership of the variable though. And in practice it's a pretty good compromise, because it's pretty hard to do this by mistake. Note: const in rust is different to const in some other languages: it represents a value that is duplicated inline into each use site at compile time.
- midjji 5y agoThe appropriate way to mark something as known compiletime is to make it constexpr, nothing else.