Hacker News new | past | comments | ask | show | jobs | submit login

Yeah their take on goto is a bit odd given that it's probably the sanest way to do "cascading" error handling in C given that we don't have RAII or exceptions.



GCC supports RAII through cleanup variable attribute (https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attribute...) though.


For small and moderate memory requirements, C pretty much supports RAII via variable-length arrays.

You just replace this:

    void f(int n)
    {
            float *x = malloc(n * sizeof*x);
            // ...
            free(x);
    }
with this:

    void f(int n)
    {
            float x[n];
            // ...
    }
edit: and you can exit your function anywhere without leaking.


They were made optional, as it turned out a very bad idea regarding security.

I just need to call your example function with the right n to corrupt the stack.


For memory allocs sure, but that's only a small subset of resource management. How about sockets, fds, locks, 3rd party library initialization, hardware setup (for device drivers) etc... Alloca doesn't cut it, you need general purpose destructors.


Also when you code something at lower levels, sometimes it’s beneficial to treat some parts of CPU state and thread state as resources: process/thread priority, interrupt mask, FPU control, even instruction set (e.g. Thumb support on ARM needs to be manually switched on/off).


sure, it's just a small, but non-negligeable, part of RAII that you can do in C


It's negligible, you still need to manage lifetimes somehow beyond the scope of a single function. Like having a context abstraction and tying destruction of resources to it. Introducing something alternative for special cases only increases complexity as now instead of using a single universal and consistent API you have multiple that behave rather differently.


in many cases (I would say most, at least for my programs in non-interactive scientific computing), all the objects can be created at the beginning of the program, and then no further creation happens. Sometimes it takes a bit of effort to refactor your program into that structure, but it is an effort well spent. Then you can use tools like openbsd's pledge, and reason more clearly about your algorithms.


I concur, that tends to be my modus operandi as well but unless your application is completely monolithic you'll probably have 3rd party init code to deal with at some point. And again it won't help if you need to handle cleanup that's not memory-related.

In the case of an operating system (the subject of TFA) pre-allocating everything is obviously completely impractical and alloca won't help since you can't return the memory outside of the stack frame. I'd wager that there are very few uses of goto in kernel code that could successfully be replaced by alloca (the fact that kernel stacks tend to be very shallow wouldn't help either).


Pre allocation is generally the safe option in a embedded security critical environment where you must always handle the worst case scenario and you know all possible inputs. In a user interaction environment though it's usually better to over-sell so that the user can choose wheter he wants to create 1 million A's or 1 million B's, instead of having a pre-created pool of half a millon A and Bs each.

With pre allocation you usually also end up creating your own resource management within the pre allocated pool and then you are back to the resource management problem...


RAII is about a lot more than freeing memory. What if that’s an array of open file handles? Or mutex locks, etc?



yeah, just like ieee754 floating point arithmetic. What's the point of your remark?




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: