Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

It's only undefined behavior if you use regular variables and regular increments. If you use the standard atomic functions/classes with std::memory_order:relaxed, it's legal, and provides what you want.


std::memory_order:relaxed would not cover my use case. This still requires locking, if we are using atomic<int> on x86 the locking is probably done at an assembly level which is much faster, but it remains locking.

Specifically, that form of locking marks a specific cache line 'locked' and blocks all processors from modifying that cache line. When you're variable happens to share that cache line with something you want quick access to, this stuf matters. (there is an exception using 'compare and swap' instructions, but I've only seen ICC emit those, not GCC.)

In general, I would expect data races to only create UB when the behavior they result in happens to be UB. In my specific example, there is no source of UB except for apparently the data race.


If you really want that, just do a relaxed read into a local variable, increment there and relaxed store afterwards. At least clang will give you exactly the assembly you want, minus the technically undefined behavior: https://godbolt.org/g/9ikt1m


memory_order::relaxed doesn't imply locking. Compilers on platforms where aligned access is atomic will generally implement relaxed reads and writes without locking, barriers or other expensive operations. So x = x + 1 with relaxed semantics should be cheap and best effort, like you want.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

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

Search: