|
|
Subscribe / Log in / New account

Moving the kernel to modern C

Moving the kernel to modern C

Posted Feb 25, 2022 9:29 UTC (Fri) by geert (subscriber, #98403)
In reply to: Moving the kernel to modern C by marcH
Parent article: Moving the kernel to modern C

> In even more advanced languages 'const' is the default

"const" is the default for /var/iables?!?


to post comments

Moving the kernel to modern C

Posted Feb 25, 2022 9:37 UTC (Fri) by ncm (guest, #165) [Link]

Let us not confuse the name with the thing named.

Moving the kernel to modern C

Posted Feb 26, 2022 0:14 UTC (Sat) by camhusmj38 (subscriber, #99234) [Link] (1 responses)

Const is the default for named values. Mutability is opt in in Rust. C and C++ have const as the opt in.
Scala has different words for mutable and non-mutable values (var and val respectively.)

Constant v Immutable

Posted Feb 28, 2022 19:10 UTC (Mon) by tialaramex (subscriber, #21167) [Link]

Rust distinguishes constants from variables which simply can't be mutated. By default you get a variable but it can't be mutated. You can declare constants instead with "const" or, if you annotate your variable with "mut" you allow the variable to be mutated subsequently.

let cannot_change = some::expression(with_variables_if_you, want);

const COMPILE_TIME: u32 = my::WayToGet::a_constant_value(PERHAPS_FROM_OTHER_CONSTANTS);

let mut count = 0; /* We will change this, presumably when counting stuff */

At compile time the constants must be well, constant, (over time the amount of labour the compiler is willing to undertake to determine what that constant *is* has increased, as it has in C++ to a much greater extent) but the ordinary immutable value is not known at compile time, yet, it is immutable (of course if it's inside the scope of a loop, it will be conjured into existence, perhaps with a new value, each time the loop runs)

This means Rust programs naturally do Kate Gregory's first step from maintaining a C++ codebase, marking everything immutable and then only marking as mutable the stuff that actually changes, so now the maintenance programmer has some idea what's actually going on.

If you're familiar with C, Rust's const is like a type-safe improvement on #define and Rust's default immutable variables are more like C's const. You may notice that the types were elided from my variable examples but not the constant, Rust insists on being explicitly told the type of constants but it will infer types for many variables from how they're defined or used.

Moving the kernel to modern C

Posted Feb 28, 2022 3:36 UTC (Mon) by marcH (subscriber, #57642) [Link] (2 responses)

> > In even more advanced languages 'const' is the default
>
> "const" is the default for /var/iables?!?

Sorry, I should used the standard name "non-modifiable lvalue"  /s

More seriously, you're highlighting a serious "const" problem in the programming languages and culture and especially in C. It's very confusing to call "constant" something in a local scope that does not change after initialization but that is _different_ everytime the including function is called. So yes, an "immutable variable" is the unfortunate and confusing name used to make that difference.

Rust does make a formal difference between 1) constant, 2) immutable and 3) mutable variables:https://doc.rust-lang.org/book/ch03-01-variables-and-muta...

Consider this example:

some_function()
{
... 
z = f(g(x1) + h(x2)) / (j(x3) - k(x4)) - l(x5) + ... ; 
...
}

There is a simple reason why most people don't write code like this and why they break it down into multiple steps: readability. Not just to avoid very long lines but to simply give a good NAME to carefully chosen checkpoints in the middle:

some_function()

  ... some code, including of course some statements and not just declarations ...

   const meaningful_name1 = f(g(x1) + h(x2) ;
const meaningful_name2 =  j(x3) - k(x4);
etc. 
 ...
}

Funny enough, I've sometimes seen this lack of intermediate "variables" being abused by people new to functional languages ("look Ma, no variables!). It's especially tempting when you have a ternary operator more readable than " cond ? A : B". I digress.

It's sad that many programming languages seem to care so little about the difference between read-only and read/write when mutability is in fact the most critical programming concept for both correctness (unintended side effects) and concurrency:
https://doc.rust-lang.org/book/ch16-00-concurrency.html

Every documentation about concurrency, locking, RCU and what not uses the words READ and WRITE every other line. Yet C does not care and calls everything "a variable". Can you see a problem / gap here?  C, the low level language  supposedly in charge of managing  memory accessed concurrently by devices and multicores got a formal memory model in... 2011! After Java and I believe by basically borrowing the C++ one. RCU and locking experts aside, the vast majority of kernel developers  underestimates or even ignores the ridicule of that C-tuation.

And of course the more read-only variables you have, the less likely you are to modify them by mistake. Can't hurt when coding in _the_ language of memory corruptions.

C has been influenced too much by the hardware engineering perspective where a variable is a memory location / register and not enough by the more "mathematical" view where a variable is just a name given to the result of some computation. Allowing declarations after statements is a baby step but into the right direction. All grown-up languages have already taken this step.

Moving the kernel to modern C

Posted Feb 28, 2022 8:17 UTC (Mon) by geert (subscriber, #98403) [Link]

Thanks, I do like the mathematical view!
And allowing declarations after statements is a requirement for making intermediate results of non-trivial processing const.

Moving the kernel to modern C

Posted Mar 1, 2022 0:09 UTC (Tue) by marcH (subscriber, #57642) [Link]

Forgot the classic reference: https://queue.acm.org/detail.cfm?id=3212479

C Is Not a Low-level Language
Your computer is not a fast PDP-11.
David Chisnall

> Caches are large, but their size isn't the only reason for their complexity. The cache coherency protocol is one of the hardest parts of a modern CPU to make both fast and correct. Most of the complexity involved comes from supporting a language in which data is expected to be both shared and mutable as a matter of course. Consider in contrast an Erlang-style abstract machine, where every object is either thread-local or immutable

Etc.


Copyright © 2025, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds