←back to thread

271 points mithcs | 7 comments | | HN request time: 1.818s | source | bottom
Show context
woodruffw ◴[] No.45953391[source]
Intentionally or not, this post demonstrates one of the things that makes safer abstractions in C less desirable: the shared pointer implementation uses a POSIX mutex, which means it’s (1) not cross platform, and (2) pays the mutex overhead even in provably single-threaded contexts. In other words, it’s not a zero-cost abstraction.

C++’s shared pointer has the same problem; Rust avoids it by having two types (Rc and Arc) that the developer can select from (and which the compiler will prevent you from using unsafely).

replies(13): >>45953466 #>>45953495 #>>45953667 #>>45954940 #>>45955297 #>>45955366 #>>45955631 #>>45955835 #>>45959088 #>>45959352 #>>45960616 #>>45962213 #>>45975677 #
1. accelbred ◴[] No.45955366[source]
Unfortunately, for C++, thats not true. At least with glibc and libstdc++, if you do not link with pthreads, then shared pointers are not thread-safe. At runtime it will do a symbol lookup for a pthreads symbol, and based off the result, the shared pointer code will either take the atomic or non-atomic path.

I'd much rather it didnt try to be zero-cost and it always used atomics...

replies(3): >>45955580 #>>45956553 #>>45956902 #
2. woodruffw ◴[] No.45955580[source]
This is, impressively, significantly worse than I realized!
3. TuxSH ◴[] No.45956553[source]
True, but that's a fault of the implementation, which assumes POSIX is the only thing in town & makes questionable optimization choices, rather that of the language itself

(for reference, the person above is referring to what's described here: https://snf.github.io/2019/02/13/shared-ptr-optimization/)

replies(1): >>45957423 #
4. eddd-ddde ◴[] No.45956902[source]
Why use atomics if you don't need them? There really should just be two different shared pointer types.
replies(1): >>45959387 #
5. wyldfire ◴[] No.45957423[source]
> the language itself

The "language" is conventionally thought of as the sum of the effects given by the { compiler + runtime libraries }. The "language" often specifies features that are implemented exclusively in target libraries, for example. You're correct to say that they're not "language features" but the two domains share a single label like "C++20" / "C11" - so unless you're designing the toolchain it's not as significant a difference.

We're down to ~three compilers: gcc, clang, MSVC and three corresponding C++ libraries.

replies(1): >>45978142 #
6. accelbred ◴[] No.45959387[source]
I wouldn't mind two types. I mind shared pointer not using atomics if I statically link pthreads and dlload a shared lib with them, or if Im doing clone3 stuff. Ive had multiple situations in which the detection method would turn off atomic use when it actually needs to be atomic.
7. TuxSH ◴[] No.45978142{3}[source]
I agree with what you said, however neither libc++ nor MS-STL have this "optimization" to my knowledge