On Thu, Jun 8, 2023 at 1:53 AM Peter Zijlstra <peterz@xxxxxxxxxxxxx> wrote: > > Or perhaps use the smart-pointer concept applied to our classes like: > > #define smart_ptr(name, var) \ > __INSTANTIATE_VAR(name, var) So this is the only situation where I think "ptr" makes sense (your "fat pointer" argument is nonsensical - sure, you can treat anything as a pointer if you're brave enough, but that just means that "pointer" becomes a meaningless word). However, I think that for "smart pointers", we don't need any of this complexity at all, and we don't need that ugly syntax. > Then we can write: > > DEFINE_CLASS(kfree, void *, kfree(THIS), p, void *p) > > smart_ptr(kfree, mem) = kzalloc_node(...); > if (!mem) > return -ENOMEM; No, the above is broken, and would result in us using "void *" in situations where we really *really* don't want that. For automatic freeing, you want something that can handle different types properly, and without having to constantly declare the types somewhere else before use. And no, you do *not* want that "kfree(THIS)" kind of interface, because you want the compiler to inline the freeing function wrapper, and notice _statically_ when somebody zeroed the variable and not even call "kfree()", because otherwise you'd have a pointless call to kfree(NULL) in the success path too. So for convenient automatic pointer freeing, you want an interface much more akin to struct whatever *ptr __automatic_kfree = kmalloc(...); which is much more legible, doesn't have any type mis-use issues, and is also just trivially dealt with by a static inline void automatic_kfree_wrapper(void *pp) { void *p = *(void **)pp; if (p) kfree(p); } #define __automatic_kfree \ __attribute__((__cleanup__(automatic_kfree_wrapper))) #define no_free_ptr(p) \ ({ __auto_type __ptr = (p); (p) = NULL; __ptr; }) which I just tested generates the sane code even for the "set the ptr to NULL and return success" case. The above allows you to trivially do things like struct whatever *p __automatic_kfree = kmalloc(..); if (!do_something(p)) return -ENOENT; return no_free_ptr(p); and it JustWorks(tm). And yes, it needs a couple of different versions of that "__automatic_kfree()" wrapper for the different freeing cases (kvfree, rcu_free, whatever), but those are all trivial one-liners. And no, I didn't think too much about those names. "__automatic_kfree" is too damn long to type, but you hated "auto". And "no_free_ptr()" is not wonderful name either. But I tried to make the naming at least be obvious, if not wonderful. Linus