Live data from Hacker News

Stupid Smart Pointers in C

blog.kevinalbs.com

131–140 of 174 posts

Re: Stupid Smart Pointers in C

#131
That's completely asinine since it can't be made to work properly with inlining (including LTO), architectures that use a shadow stack or don't use a frame pointer, and also ridiculously inefficient and requiring assembly code for all architectures.

Use C++ or __attribute__((cleanup)) instead.

Re: Stupid Smart Pointers in C

#132
post #14

Earlier quoted context omitted.

> __attribute__((cleanup)) Interesting. I'm not very proficient in C, this looks like some sort of finalizers for local variables?

Correct. You can use it in a simple way to free memory, but we've also used it to create scoped locks[1]. This being C, it's not without its problems. You cannot use it for values that you want to return from the function (as you don't want those to be freed), so any such variables cannot be automatically cleaned up on error paths either. Also there's no automated checking (it's not Rust!) Note it's {...} scoped, not…

You can just zero out the pointer variable with __attribute__((cleanup)) before returning its value (from a temporary copy of course).

Re: Stupid Smart Pointers in C

#133
post #130
post #104

Earlier quoted context omitted.

I've heard enough "C is superior to C++" arguments from game developers who then go and use header structs for inheritance, or X macros, enums, and switch statements for virtual functions, to know that more complexity isn't an issue as long as people feel clever and validated.

X macros can do tons of stuff C++ can't. And if you stick with C, you avoid mountains of C++ problems, even with all the stuff you're talking about.

I love using x macros with c++ to create static types and hooks to disambiguate from basic types. This is more applicable to final executables than libraries - I would never provide anyone with an API based on the mess it creates, but it allows application code to be strongly checked and makes it really easy to add whole classes of assertions to debug builds.

Re: Stupid Smart Pointers in C

#134
post #5

Really, don't do this, it's a portability and safety nightmare (aside from C not being memory safe already). C programmers are better off with either of these two techniques: * Use __attribute__((cleanup)). It's available in GCC and Clang, and we hope will be added to the C spec one day. This is widely used by open source software, eg. in systemd. * Use a pool allocator like Samba's talloc ( https://talloc.samba.org/…

https://github.com/acbits/reftrack-plugin

Hey, I wrote this GCC plugin to automate reference counting in C. Any bug reports welcome.

Re: Stupid Smart Pointers in C

#136
post #56

Earlier quoted context omitted.

For me, the point of writing something in C is portability. There were C compilers 30 years ago, there are C compilers now, and there will almost certainly be C compilers 30 years from now. If I want to write a good, portable library that's going to be useful for a long time, I'll do it in C. This is, at least, the standard in many gamedev circles (see: libsdl, libfreetype, the stb_* libraries). Under that expectatio…

The bad news is that C23 broke a lot of existing code[1]. We had to do a lot of work in Fedora to fix the resulting mess. [1] https://gcc.gnu.org/gcc-15/porting_to.html#c23

> Note that the bool type is not the same as int at ABI level,

Huh. Wonder what the benefits of that are. Bools being ints never struck me as a serious problem. I wonder if this catches people who accidentally assign rather than compare tho....

Re: Stupid Smart Pointers in C

#137
post #20

Earlier quoted context omitted.

That's sad. Having migrated from C++ to golang a few years ago, I find defer vastly inferior to C++ destructors. Rust did it right with its drop trait, I think it's a much better approach

What's "drop trait" for C? There are no any traits in C.

Parent post said Rust.

edit: TIL: Looks like the [drop trait][1] is an opt-in destructor that the Rust compiler understands.

[1]: https://doc.rust-lang.org/nomicon/dropck.html

Re: Stupid Smart Pointers in C

#138

I maintain a combined error and resource state per thread. It is first argument to all functions. If no errors, function proceeds - if error, function instead simply immediately returns. When allocating resource, resource is recorded in a btree in the state. When in a function an error occurs, error is recorded in state; after this point no code executes , because all code runs only if no errors. At end of function i…

Why bother freeing before exit?

Re: Stupid Smart Pointers in C

#139

Earlier quoted context omitted.

libc allocator is considered "slow" for the extra overhead it has. I'll just leave it at that as you can GPT the rest. I did some of my own testing back in the days I wrote C, and mine was significantly faster than malloc/free. It's also a way, I suppose, to ensure your program has the memory it needs, depending on how you design it. Mine basically allocates all the expected memory I need at the start, while still be…

Of course the libc allocator is slow, it's designed as a one-size-fits-all solution that's poorly tuned for most workloads and often doesn't get substantially updated for decades. By writing your own, you aren't avoiding an allocator, you're just avoiding the libc implementation of an allocator. (In fact, most libcs let you just redefine the malloc(), free(), and realloc() functions to point to your own allocator ins…

I guess I'm confused at this chain of responses, then. As I'm doing what you are already suggesting.

Re-reading your comment, about the "not really freeing anything" -- I beg to differ, as when you do a real free(), it frees up memory for any program to use. As I already mentioned one of the benefits is once you have control of who can use that memory and aren't risking it not being available - disregarding some program that constantly grows in memory.

Re: Stupid Smart Pointers in C

#140
post #5

Really, don't do this, it's a portability and safety nightmare (aside from C not being memory safe already). C programmers are better off with either of these two techniques: * Use __attribute__((cleanup)). It's available in GCC and Clang, and we hope will be added to the C spec one day. This is widely used by open source software, eg. in systemd. * Use a pool allocator like Samba's talloc ( https://talloc.samba.org/…

> ... plus [reference counting] interacts badly with how modern CPUs work.

Can you expand on this?

Post reply on HN