Live data from Hacker News

Cake – C23 and Beyond (2023)

thradams.com

101–110 of 128 posts

Re: Cake – C23 and Beyond (2023)

#101

Earlier quoted context omitted.

Having to change how you write your program is the worst case of suffering compiler shenanigans that I can think of.

If you want to keep doing programming in a way you are already familiar with, and are not willing to change your way of thinking about programs, yes then it's a bad fit. If you want to write reliable programs, there is evidence that changing the way we think about and express programming problems, can have substantial effects on reliability.

You're assuming too much.

Not saying we shouldn't change anything.

I am saying that adding ownership is't the change that's needed, since you won't be able to convert most C code to that regime.

Re: Cake – C23 and Beyond (2023)

#102
post #56

Earlier quoted context omitted.

>If it were that simple, someone would have had success at scale by now A lot of code in that article doesn't use mempools, and furthermore, just because a double free exists doesn't mean that its always exploitable. And if its exploitable, it doesn't mean that you can gain a shell or even exfil data, sometimes it means you can just crash the program. Fundamentally, if you write a wrapper around memory management tha…

malloc() already keeps track of every memory allocation. Just what kind of tracking are we talking about here?

malloc doesn't keep track accurately in all cases, which is why double free is possible in the first place.

with mempool implementation, you shouldn't be able to release a previously released chunk because the pointer to that chunk will be zeroed out. This requires one more level of indirection in accessing the memory, i.e pointer to a struct that contains the pointer to the memory, but is otherwise safe.

As of note that may be causing some confusion, im not referencing the standard linux mempool implementation. I have written custom ones with a lot of helper functions for safe memory access.

Re: Cake – C23 and Beyond (2023)

#103
post #98

Earlier quoted context omitted.

If you want to keep doing programming in a way you are already familiar with, and are not willing to change your way of thinking about programs, yes then it's a bad fit. If you want to write reliable programs, there is evidence that changing the way we think about and express programming problems, can have substantial effects on reliability.

You don't need a borrow checker to write reliable programs. If anything the Rust obsession with memory safety has been harmful since it detracts from general safety. But don't take my word for it, maybe consider what the co-author of The Rust Programming Language, 2nd edition has to say [1]. If you really care about writing robust programs then focus on improving your testing methodology rather than fixating on the p…

Memory safety is a good thing to obsess over. It's just that we don't need ownership and borrow checking to get there.

Re: Cake – C23 and Beyond (2023)

#104

Earlier quoted context omitted.

Not sure I agree with that premise as the cake source would have been written in a way to be compatible with ownership annotations from the get go vs retrofitting an existing codebase. Help me understand how something like this composes: FILE* open_file(const char* p) { FILE* owner f = … return f; } Now open_file callers would need to know that ownership is being returned which means that local variables would need t…

Not sure if I understood. the usage of old and new (checked and unchecked) is a challenge.We may have the same headers used in both codes. The other challenging is that same source may compile in compiler with or without support. Ownership Feature Strategy (Inspired by stdbool.h) If the compiler supports ownership checks and qualifiers such as _Owner, _View, _Obj_view, etc., it must define __STDC_OWNERSHIP__. However…

To me ownership composability means you can express ownership locally without it infecting anything outside of that local scope. However, ownership is not always tied to lexical scope and in those cases it doesn’t compose. In other words, you can add all the annotations you want locally and a) the code will still be incorrect b) the code may not compile as you show in your other snippet because now the function signature needs to contain the ownership sigil which then results in all callers needing the ownership sigil. Disabling it partially only emulates composition if the callers are in external files compiled with alternate options / skipping ownership validation. If you have local calls to the newly annotated function, you’ll be back into needing to fix the entire file’s annotations.

Unless I misunderstood what OP meant about ownership composition.

Re: Cake – C23 and Beyond (2023)

#105

Earlier quoted context omitted.

I can't say I understand the overall point you're trying to make.

You're working with embedded C that is a rats nest of macros. It could instead be sanely factored and readable C without the macros if it was written with slightly more trust in the compiler.

...and you're willing to use nonstandard attributes, code generators, and a custom preprocessor. At this point, why not C++, seriously?

And can you show me an example of an existing framework for embedded device that's not the spaghetti code I showed?

Re: Cake – C23 and Beyond (2023)

#106
post #90

Earlier quoted context omitted.

True, but with some stuff you just ain't gonna need it. For example, chibicc forks a process for each input file. They're all ephemeral. So the fork/_exit model does work well for chibicc. You could compile a thousand files and all its subprocesses would just clean things up. Now needless to say, I have compiled some juicy files with chibicc. Memory does get a bit high. It's manageable though. I imagine it'd be more…

(I think preprocessor is the place where memory is used and released all the time while expanding macros.)

It is.

Re: Cake – C23 and Beyond (2023)

#107
post #52

Earlier quoted context omitted.

If you are talking about a very naive version of mempool, then you are correct, but thats why I said a good implementation. The whole point of a good mempool is that you malloc once, and only call free when you exit the program. The data structures for memory allocation will never get corrupted. And the memory pool will never release chunk twice cause it keeps tracks of allocated chunks. User after free is mitigated…

> If you are talking about a very naive version of mempool, then you are correct, but thats why I said a good implementation. No true Scotsman. > The whole point of a good mempool is that you malloc once, and only call free when you exit the program. The data structures for memory allocation will never get corrupted. And the memory pool will never release chunk twice cause it keeps tracks of allocated chunks. Then yo…

Its not about comparing implementations, its about the fact that a correct mempool implementation solves the problem without need for complex borrow checkers.

For example, in that implementation, you request memory from a mempool, it returns a chunk-struct with the pointer to allocated memory, the size of the chunk, and optionally some convenience functions for safe access (making sure that the pointer is not incremented or decremented beyond the limits). It also keeps its own pointer to the chunk-struct, along with the chunk that it was allocated. When you release the chunk, it zeros out the pointer in the chunk-struct. Now any access to it will cause a segfault.

You can of course write code that bypasses all those checks, but in Rust, thats equivalent to using unsafe when you wanna be lazy. Also you could argue that Rust is better because instead of segfaulting, the check will be caught during compile time, which is true but only for fairly simple programs. Once you start using RefCells, you cannot guarantee everything during compile time.

Re: Cake – C23 and Beyond (2023)

#108

Earlier quoted context omitted.

Converting code can be challenging. The cake code has been successfully converted. null-checks are not ready, and something similar already happened to c#. The experience is similar to changing a header file to use a const argument where previously the argument was non-const. This change will propagate everywhere. I also think a similar experience is converting JavaScript to typescript. The type system will complain…

Have you made OpenSSL, or something big like that, completely memory safe this way? As in, running nothing but memory-safety-ified C code down to the syscall boundary?

The ownership checks are new in Cake, less than one year. So the answer is no, just cake is using. And there is a lot of work to do..in flow analysis etc.

The cake source itself is moving to another experimental feature that is nullable types.

Similar of C# https://learn.microsoft.com/en-us/dotnet/csharp/nullable-ref...

Re: Cake – C23 and Beyond (2023)

#109

I might be missing something, but this seems to require ownership annotations on all functions, e.g. a compatible and correct prototype for `fclose` to correctly note that the owned `FILE *` is moved into the call. If that's correct, then this is somewhat practically limited: either pre-existing codebases will need to be retrofitted with an essentially bespoke set of macros, or the compiler will need to be "fail open…

Compilers cheat when working with known libraries - they don't need annotations on known functions, much like they don't need the specific implementation of them to know the semantics. This occasionally goes wrong when the compiler assumes any function with a given name must be that function from libc, e.g. the programmer writes a function called `sin`, there's a risk of it being mistaken for the libm function.

Right. It's less known libraries I'm worried about (libc can easily be layered over, as you've said) and more unknown ones.

In particular: there are a lot of ~universally used libraries with ludicrously complex C APIs that undergo significant own/borrow semantic changes between releases. Things like OpenSSL. These libraries will need to carry these annotations upstream for correctness and up-datedness reasons.

Re: Cake – C23 and Beyond (2023)

#110
post #56

Earlier quoted context omitted.

malloc() already keeps track of every memory allocation. Just what kind of tracking are we talking about here?

malloc doesn't keep track accurately in all cases, which is why double free is possible in the first place. with mempool implementation, you shouldn't be able to release a previously released chunk because the pointer to that chunk will be zeroed out. This requires one more level of indirection in accessing the memory, i.e pointer to a struct that contains the pointer to the memory, but is otherwise safe. As of note…

What is mempool? Is that this? https://en.wikipedia.org/wiki/Region-based_memory_management
Post reply on HN