Live data from Hacker News

Cake – C23 and Beyond (2023)

thradams.com

51–60 of 128 posts

Re: Cake – C23 and Beyond (2023)

#51
post #27

C safety addons like this (there have been many) is that they don't prevent extracting raw pointers from controlled pointers. Optional memory safety isn't. > If this can be reasonably retrofitted to existing libraries and projects That's the problem. If you want to fool around in this space, consider revisiting C++ to Rust conversion. There's something called Corrode, which compiles C to a weird subset of Rust full o…

    Bad guesses will result in programs that subscript out of range, which is caught at run time.
That is sadly not always the case.

Re: Cake – C23 and Beyond (2023)

#52

Earlier quoted context omitted.

mempool does not solve double free, use after free (at least at compile time) or fopen sample. But mempool and ownership can be complementary.

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 you've just moved the same problem one layer up - "use after returned to mempool" takes the place of "use after free" and causes the same kind of problems.

> When you allocate, you get a struct back that contains a pointer to the data. When you release, that pointer is zeroed out.

And the program - or, more likely, library code that it called - still has a copy of that pointer that it made when it was valid?

Re: Cake – C23 and Beyond (2023)

#53

Earlier quoted context omitted.

Everything related to safety is on my list. (the list is big) I think big problems can be broken down into smaller ones.

I don't think it's very compelling to convert C code to a thing that gives you a safety half-measure. You'll still have security bugs, so it'll just feel like theatre.

huh? There are also security bugs in Rust, so it is theatre as well?

Pointer ownership could eliminate a class of bugs. And such an approach can be combined with run-time checks for bounds and signed overflow, and then you have a memory-safe C more or less (some minor pieces are still missing, but nothing essential),

Re: Cake – C23 and Beyond (2023)

#54
post #27

C safety addons like this (there have been many) is that they don't prevent extracting raw pointers from controlled pointers. Optional memory safety isn't. > If this can be reasonably retrofitted to existing libraries and projects That's the problem. If you want to fool around in this space, consider revisiting C++ to Rust conversion. There's something called Corrode, which compiles C to a weird subset of Rust full o…

>Can you ask Github Co-pilot to look at C code and answer the question "What is >the length of the array 'buf' passed to this function"? That tells you how to >express the array in a language where arrays have enforced lengths, whicn >includes both C++ and Rust this is the way you tell C what is the size of array. void f(int n, int a[n]) { }

Do you have source on this syntax? Does the `[n]` actually do anything here? Fooling around in godbolt, `void f(int n, int a[n]) {` is the same as `void f(int n, int a[]) {` and doesn't appear to change assembly or generate any warnings/errors with improper usage.

Re: Cake – C23 and Beyond (2023)

#55

Earlier quoted context omitted.

I’d rather just have memory safety. If all you give me is half measures, then I’ll either just use plain old C/C++ or I’ll switch to a totally different language. Maybe one with a GC so I don’t have to please some ownership thingy.

I think it's a common misconception that ownership is there to make you suffer compiler shenanigans. When in my experience it changes the way you model programs. Turns out, that structuring your program in a way were it's clear who owns what makes for easier to understand and debug programs. It's a bit analogous to static typing, saying I'll use a language like Python without type hints, because its gonna make me avo…

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

Re: Cake – C23 and Beyond (2023)

#56

Earlier quoted context omitted.

Compiler optimizations and other forms of UB like integer overflow would like a word with you. If it were that simple, someone would have had success at scale by now https://alexgaynor.net/2020/may/27/science-on-memory-unsafet... .

>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?

Re: Cake – C23 and Beyond (2023)

#57
post #27

C safety addons like this (there have been many) is that they don't prevent extracting raw pointers from controlled pointers. Optional memory safety isn't. > If this can be reasonably retrofitted to existing libraries and projects That's the problem. If you want to fool around in this space, consider revisiting C++ to Rust conversion. There's something called Corrode, which compiles C to a weird subset of Rust full o…

>Can you ask Github Co-pilot to look at C code and answer the question "What is >the length of the array 'buf' passed to this function"? That tells you how to >express the array in a language where arrays have enforced lengths, whicn >includes both C++ and Rust this is the way you tell C what is the size of array. void f(int n, int a[n]) { }

You can write that in C, but it doesn't really do anything. It's equivalent to

    void f(int n, int a[]) {
    }
Why? So that you can write

    void f(int n, int m, int a[n][m]) {
    }
which declares a 2-dimensional array parameter. In that case, the "m" is used to compute the position in the array for a 2D array. The "m" doesn't do anything. This is equivalent to writing

   void f(int n, int m, int a[][m]) {
   }
This is C's minimal multidimensional array support, known by few and used by fewer.

Over a decade ago, I proposed that sizes in parameters should be checkable and readable I worked out how to make it work.[1] But I didn't have time for the politics of C standards.

[1] http://animats.com/papers/languages/safearraysforc43.pdf

Re: Cake – C23 and Beyond (2023)

#58

Earlier quoted context omitted.

mempool does not solve double free, use after free (at least at compile time) or fopen sample. But mempool and ownership can be complementary.

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…

> The whole point of a good mempool is that you malloc once, and only call free when you exit the program

So you're describing fork() and _exit(). That's my favorite memory manager. For example, chibicc never calls free() and instead just forks a process for each item of work in the compile pipeline. It makes the codebase infinitely simpler. Rui literally solved memory leaks! No idea what you're talking about.

Re: Cake – C23 and Beyond (2023)

#59
I've been dabbling in embedded programming. Everything is written in C. I just don't understand why. C++ solves pretty much all problems if you want it too (RAII, smart pointers, move semantics) and the frameworks writers wouldn't need to implement their bespoke OOP system on top of opaque pointers and callbacks.

Maybe it was bad luck on my part, and other embedded frameworks are better; but I got into both ESP32 and STM32, both frameworks are the worst spaghetti code I have ever seen. You need to jump through at least one, often two layers of indirection to understand what a particular function call will do. Here's an example of what I mean:

    // peripheral_conf.h
    #define USE_FOOBAR_PERIPHERAL 1
    // obj_t.h
    #define USE_OBJ_PARAM2

    // In the library header
    #ifdef USE_FOOBAR_PERIPHERAL
    #define DoSomethingCallback FoobarCallback
    #endif

   // foobar.h
   status_t FoobarCallback(int32_t data, int32_t param);

    // obj_t.c
    status_t Init(Obj_t* obj) {
        obj->param1 = obj->init.initparam & 0xFF;
        #ifdef USE_OBJ_PARAM2
        obj->param2 = (obj->init.initparam >> 16) & 0xFF;
        #endif
        obj->callback = DoSomethingCallback;
        return OK;
    }
    
    status_t DoSomething(Obj_t *obj, int32_t data) {
        #ifdef USE_OBJ_PARAM2
        return obj->callback(data, obj->param2);
        #else
        return obj->callback(data, obj->param1);
        #endif
    }

    // main.c
    Obj obj = {0};
    obj.init.initparam = 0x12345678;
    Init(obj);
    DoSomething(obj, 0x42);
And that's an easy example. Macros everywhere, you need to grok what's happening in four different files to understand what the hell a single function call will actually do. Sure, the code is super efficient, because once it's compiled all the extraneous information is pre-processed away if you don't use such and such peripheral or configuration option. But all this could be replaced by an abstract class, perhaps some templates... And if you disable stuff you may not need (RTTI, exceptions) then you'd get just as efficient compiled code. It would be much easier to understand what going on, and you wouldn't be able call DoSomething on uninitialized data... Because you'd have to call the constructor first to even have access to the method.

Anyway, thank god for debuggers, step-by-step execution, and IDEs.

Re: Cake – C23 and Beyond (2023)

#60

I've been dabbling in embedded programming. Everything is written in C. I just don't understand why. C++ solves pretty much all problems if you want it too (RAII, smart pointers, move semantics) and the frameworks writers wouldn't need to implement their bespoke OOP system on top of opaque pointers and callbacks. Maybe it was bad luck on my part, and other embedded frameworks are better; but I got into both ESP32 and…

> But all this could be replaced by an abstract class, perhaps some templates... And if you disable stuff you may not need (RTTI, exceptions) then you'd get just as efficient compiled code.

Isn't it just that your personal in-head GPT has been trained on C++ and wants to see it everywhere? It's not so easy to make very small embedded implementations and there's a reason after 25+ years C++ has not made inroads there.

Post reply on HN