Earlier quoted context omitted.
The perf difference was due to the compiler being able to infer 'const' by way of 'static'. Advocating 'static' when your actual intent is 'const' does less experienced readers a disservice; they will assume that 'static' is meant to make things faster, and be disappointed when it doesn't work for non-constant values.
I am not advocating static. I'm advocating for looking at what the compiler outputs when surprising behavior is encountered. The example is extracted from a larger piece of code, and I reported the minimal case as-is. If anything, the title is meant to be read as "isn't it amusing that something apparently unrelated such as `static` causes a performance improvement". That said, I have added a note clarifying this at…
When static makes your C code 10 times faster
91–100 of 113 posts
Re: When static makes your C code 10 times faster
#92Earlier quoted context omitted.
The compiler only operates on one unit (file) at a time so it has literally no way of telling this in C. There are legitimate uses for having a non-const global which is never modified by local source: library config options, hooks for external programs, and what not. As you say, this would be a job for the linter.
You can get pretty far with a compiler warning like "warn if a global isn't preceded by an 'extern' declaration". Also, LTO does have enough information to warn about these things, especially with default hidden visibility.
LTO could handle this if you're compiling an executable, but not a library.
Re: When static makes your C code 10 times faster
#93Earlier quoted context omitted.
I really wish Zig had followed Rust’s lead and made variables const by default :/
Variables 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.
Re: When static makes your C code 10 times faster
#94My first C intuition would be defining this value as a macro. If I was in C++, then a const would make sense.
Re: When static makes your C code 10 times faster
#95Earlier quoted context omitted.
Variables 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.
How do you set a variable as mutable after the fact in rust?
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.
Re: When static makes your C code 10 times faster
#96If I could travel back in time I'd tell Dennis to make "static" the implicit default, and have a special keyword like "public" or "export" for items that are meant to be accessible from outside the compilation unit. I'd also ask him to make "switch" break by default. Then I'd go kill Hitler or something.
That said, I'm more annoyed at C's design commitee to not being able to add new features such as having length-aware arrays in C in the language.
Re: When static makes your C code 10 times faster
#97Without `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 int value; int get_value(); int main() { value = 123456789; printf("%d\n", get_…
Yes, see last few paragraphs of the post, in which I also speculate why GCC doesn't infer that there is only one compilation unit.
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.
Re: When static makes your C code 10 times faster
#98Re: When static makes your C code 10 times faster
#99Title rephrase: When the compiler can assume your values don't change magically, it can optimize their use. This is true for restricted pointers, for global-scope variables which can only be accessed in the same translation unit, for stuff in inlined functions (often), etc. -------------------------------------------- const is a bit shifty. const makes the compiler restrict what it allows you to write, but it can sti…
Specifically it's well-defined behavior to mutate an object after const_cast-ing away constness if the object wasn't const to begin with (const references or const pointers can refer to non-const objects). In your first example you have `int x = 1;` which isn't const, so the compiler has to assume that `f` may mutate it after const casting. In your second example you have `const int x = 1;` which is const so the comp…
Re: When static makes your C code 10 times faster
#100Earlier quoted context omitted.
You can get pretty far with a compiler warning like "warn if a global isn't preceded by an 'extern' declaration". Also, LTO does have enough information to warn about these things, especially with default hidden visibility.
The global must be declared without "extern" somewhere or else no memory is allocated for it. LTO could handle this if you're compiling an executable, but not a library.
That's not the correct distinction, that's why I said default vs hidden visibility.
Libraries typically export more symbols but executables can also export them eg for plugins.