Is changing a pointer considered an atomic action in C?

Solution 1:

As others have mentioned, there is nothing in the C language that guarantees this, and it is dependent on your platform.

On most contemporary desktop platforms, the read/write to a word-sized, aligned location will be atomic. But that really doesn't solve your problem, due to processor and compiler re-ordering of reads and writes.

For example, the following code is broken:

Thread A:

DoWork();
workDone = 1;

Thread B:

while(workDone != 0);

ReceiveResultsOfWork();

Although the write to workDone is atomic, on many systems there is no guarantee by the processor that the write to workDone will be visible to other processors before writes done via DoWork() are visible. The compiler may also be free to re-order the write to workDone to before the call to DoWork(). In both cases, ReceiveResultsOfWork() might start working on incomplete data.

Depending on your platform, you may need to insert memory fences and so on to ensure proper ordering. This can be very tricky to get right.

Or just use locks. Much simpler, much easier to verify as correct, and in most cases more than performant enough.

Solution 2:

The C language says nothing about whether any operations are atomic. I've worked on microcontrollers with 8 bit buses and 16-bit pointers; any pointer operation on these systems would potentially be non-atomic. I think I remember Intel 386s (some of which had 16-bit buses) raising similar concerns. Likewise, I can imagine systems that have 64-bit CPUs, but 32-bit data buses, which might then entail similar concerns about non-atomic pointer operations. (I haven't checked to see whether any such systems actually exist.)

EDIT: Michael's answer is well worth reading. Bus size vs. pointer size is hardly the only consideration regarding atomicity; it was simply the first counterexample that came to mind for me.

Solution 3:

You didn't mention a platform. So I think a slightly more accurate question would be

Are pointer changes guaranteed to be atomic?

The distinction is necessary because different C/C++ implementations may vary in this behavior. It's possible for a particular platform to guarantee atomic assignments and still be within the standard.

As to whether or not this is guaranteed overall in C/C++, the answer is No. The C standard makes no such guarantees. The only way to guarantee a pointer assignment is atomic is to use a platform specific mechanism to guarantee the atomicity of the assignment. For instance the Interlocked methods in Win32 will provide this guarantee.

Which platform are you working on?

Solution 4:

The cop-out answer is that the C spec does not require a pointer assignment to be atomic, so you can't count on it being atomic.

The actual answer would be that it probably depends on your platform, compiler, and possibly the alignment of the stars on the day you wrote the program.

Solution 5:

'normal' pointer modification isn't guaranteed to be atomic.

check 'Compare and Swap' (CAS) and other atomic operations, not a C standard, but most compilers have some access to the processor primitives. in the GNU gcc case, there are several built-in functions