Threadsafety(in this context) means that any sequence of calls of const-functions from any number of threads will have the same result. In your case there is a single const function, and you may call calc(0) from several threads and it always will return the same value. So it is pretty threadsafe.
Replace int with long long on a 32-bit system, and the stance remains the same. But you are right, as written it is thread safe in the given context. :-)
Doesn't matter: any sequence of calls for calc() from any number of threads will always yield the same result.
Mutating m1 non-atomically is completely unrelated here, because non-const functions may be not threadsafe. You should just ensure that const functions are threadsafe.
I think he's trying to get at what happens if an operation becomes non-atomic. In the case of the long long, there could be two register loads, rather than one. Normally, you would expect calc(1) to return m1 at t0, or m1 at t1, dependent on when the change thread hits. However, if your operation requires two register loads (long long on 32), you would have a third value produced, which is neither m1 at t0 or m1 at t1.
This could be considered a non-thread safe operation.
I understand the problem with non-atomicity, but it has nothing to do with thread-safety of calc().
Executing non-threadsafe function, and threadsafe function simultaneously is not a threadsafe operation. But the article says nothing about such situations, it places no restrictions on such situations. The thread-safe requirenment is for const-functions.
The only time I could see that not being threadsafe is with something like a double on a system without native support, such that bits could change during operation. Even then I think the information gets pulled out.
On most systems, the value of calc will still be a race condition dependent on what thread gets there first, even if you lock around m1 or make it atomic. Calc will pull the value from m1 into a register, perform the operation, then return the newly calculated value. Another thread changing m1 will not matter.
class c { int m1; public: void set_m1( int i ) { m1 = i; } int calc( int i ) const { return m1 * 10; } };
calc is properly const, but it's not threadsafe.