Swift / C interop, struct data change in Swift not updating back in C

Viewed 132

I have a C struct

struct Test {
  int a;
}

typedef struct Test Test;

and in C I create a pointer,

Test* myTestPointer = new Test();

I obtain the struct pointer myTestPointer in Swift, and I have checked the pointer does indeed point to the correct address in both Swift and C.

But I'm having some difficulty understanding why the following two pieces of code are not equivalent as measured by the value of a back in the C code?

let x = myTestPointer
x!.pointee.a = 123     // correctly changes the memory, as reflected back in C code
var x = myTestPointer!.pointee
x.a = 123  // does not reflect change back in C code
1 Answers

The assignment of the expression myTestPointer!.pointee (of type Test) to the variable x causes a copy of the struct.

The change to x.a effects this copy, but not the one pointed to by the pointer.

In actuality, struct copies are really often completely collided by the optimizer, but in this case, I think a copy always happens, because a pointer can act like a black box that enables any manner of external state observation/mutation.

In any case, you should not try to communicate differences in state back/forth between Swift and C (or frankly, between any two components of any software system) by mutation of shared state. Of course some times you need to, for performance reason, for building other communications primitives (e.g. building a message queue between processes, backed by an underlying shared memory region), but in general, this approach is begging for race conditions and weird synchronization difficulties.

Related