ctypestypecasting-operator

Is typecasting an atomic operation?


I'm interested in general concept not in specific solution.

If we have type casting like this:

  int x;
  float y;
  y = (float) x;

Disasm:

main:
        push    rbp
        mov     rbp, rsp
        pxor    xmm0, xmm0
        cvtsi2ss        xmm0, DWORD PTR [rbp-4]
        movss   DWORD PTR [rbp-8], xmm0
        nop
        pop     rbp
        ret

Is type casting operation itself is atomic?

Can it be somehow preempted?

Cant we get an undefined behaviour if in time of casting another process/thread changed half of the bytes in x?


Solution

  • Atomicity is about accessing objects in memory.

    Converting between types is an operation on values, not on objects. Therefore, converting has no relationship to atomicity.

    Your question seems to presume that y = (float) x; might be some sort of single operation that converts an int value stored in x to a float value in y. However, this is not the case. In y = (float) x);, there are three operations:

    1. x is loaded: x is an lvalue that designates an object in memory. Per C 2018 6.3.2.1 2, this lvalue is converted to the value stored in x. In other words, the value of x is loaded from memory. (If x were atomic, it would be an atomic load.) The result of this operation is merely a value, not an object. In particular, it is not atomic, even if x was atomic; C 2018 6.3.2.1 2 says “… if the lvalue has atomic type, the value has the non-atomic version of the type of the lvalue…”
    2. The value is converted: (float) is a cast operator that says to convert the value to float. This conversion is performed using the value, not any object. The result is a float value.
    3. The value is stored in y: y = says to store the value in y. (If y were atomic, it would be an atomic store.)

    Can it be somehow preempted?

    Cant we get an undefined behaviour if in time of casting another process/thread changed half of the bytes in x?

    Since x is not atomic, if some other thread changes x in the middle of it being loaded, the load operation could get a bad value for x.

    This does not affect the conversion to float; that is a separate operation.