char my_array[10];
Let's say threadA
changes the value of my_array[0]
and threadB
changes the value of my_array[1]
, is this thread safe?
A similar question has already been asked Is access to different elements in a C array thread safe?, and people have answers that it is thread safe, but I am not convinced about that.
Because since arrays cannot have padding bytes between elements, and usually architectures access (read/write) multiple bytes at a time, that means changing the value of my_array[0]
would result in writing adjacent array elements which may have changed in the meantime.
What about c11 and c2x?
After reading the comments below, I decided to edit my question to better fit my specific case.
What about embedded platforms? where CPUs are mostly single core and often without traditional cache.
Because since arrays cannot have padding bytes between elements, and usually architectures access (read/write) multiple bytes at a time, that means changing the value of
my_array[0]
would result in writing adjacent array elements which may have changed in the meantime.
You're overthinking this, in part by failing to distinguish between a C program's abstract machine semantics and the underlying physical machine semantics. C language implementations are responsible for bridging that gap on behalf of programmers. You don't have to care what the actual read and write sizes are. Your C implementation is responsible for producing effects as if only one char
is modified in response to an assignment to a single element of your array of char
. One of the points of writing programs in C instead of in assembly language is that you don't have to care how it does that.
And whether that actually requires any specific attention is architecture-dependent. Many architectures do have instructions for single-byte reads and writes, and with respect to those, any considerations related to a wider underlying memory-access size are handled in hardware. Similarly for cache coherency issues on multi-core machines with local cache. Handling such things may slow down your program and make the CPU work harder, but you should not be concerned about memory modifications arising apparently out of thin air.
In any case, the semantics and constraints of multithreaded programs are a question of the threading implementation used. The kind of write conflict you describe generally is not a problem because the people who implement threading libraries good enough to become widely used are well aware of them. They write their libraries in a way that ensures that to whatever extent such issues need to be attended to in software, they are handled transparently to the library user.
Note also that arrays are not a special case here. Except possibly on some exotic architectures, and with a few caveats, substantially any object might be adjacent in memory to substantially any other object. In the general case, standard C does not define a reliable means for you even to know, so if a threading library for C required programmers to protect not only against concurrent access to the same object, but also against concurrent access to nearby objects, then that library would be impractical to the point of being unusable.
What about embedded platforms? where CPUs are mostly single core and often without traditional cache.
What about them? Nothing above is specific to any particular hardware or machine architecture details. To whatever extent you have exposure to such details, your question is not about C. It might be about a particular library or C implementation, or about assembly programming, or about some IDE or SDK for your target, but you didn't ask about any of those.