On 25/01/2018 00:35, Andrey Semashev wrote:
I would like to ask for the community opinion on the naming of the (op)_and_test functions that appeared in Boost.Atomic 1.66.
For clarity, I was the one who filed the issue mentioned in the OP. My argument is the following: * "if (x)" is true when x is an integer type that is nonzero. (And this convention is often extended to non-integer types as well, for suitable definitions of "zero".) * "atomic_flag::test_and_set" is true when the flag was previously set. * "atomic<T>::bit_test_and_set" is true when the bit was previously 1/set. * "atomic<T>::fetch_add" returns the value prior to the add, which is true if nonzero due to the first rule. It thus seems peculiar to have "atomic<>::add_and_test" return true when the result is zero. I can understand why this was done, as it's a natural consequence of the assembly implementation that tends to operate around a "zero flag" rather than a "nonzero flag", but it seems strongly counter-intuitive as an interface in a higher level language. To me at least, "test" itself implies "return true if non-zero", partly as a consequence of these other things. So "bit_test_and_set" would fundamentally mean "test if the bit is non-zero, then set it and return the result of the prior test"... which is indeed what it does. And "add_and_test" would fundamentally mean "add this and return true if the result is non-zero"... which is *not* what the current implementation does. (And I know someone's probably going to raise POSIX's test(1) as a counter-argument, which is true when zero. But that's because it follows the shell's truthiness conventions, which are different from those of C/C++.)