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

My only major objection to C++ magic statics is that you can only use them for statics. Sometimes you find yourself with a task that needs to be done once per object instead of globally, and you've got to roll your own, and then you might as well use that same mechanism for globals too.

My minor objection to magic statics is that you don't have control over the size or packing of the control word, and it usually ends up being something awkwardly mid-sized like a size_t where normally you'd want it either as small as possible or cache-line sized.

I like to handle this something like this:

     void once(char _Atomic *flag, void (*fn)(void *ctx), void *ctx) {
         char st = atomic_load_explicit(flag, memory_order_acquire);
         if (st == 0 && atomic_compare_exchange_strong_explicit(flag, &st, 1,
                                                                memory_order_acquire,
                                                                memory_order_acquire)) {
             fn(ctx);
             atomic_store_explicit(flag, st=2, memory_order_release);
         }
         while (st != 2) { st = atomic_load_explicit(flag, memory_order_acquire); }
      }
There's a commented version here: https://github.com/mtklein/best/blob/main/once.c



You can use std::once_flag and std::call_once from <mutex> instead of rolling your own atomic solution.


What does C++ have to do with this submission?




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

Search: