21

Assume you've got the following definitions:

struct X
{
  char a, b;
};

X x;

And now assume you have two threads, one of which reads and writes x.a but never accesses x.b while the other one reads and writes x.b but never accesses x.a. Neither thread uses any locks or other synchronization primitives. Is this guaranteed to work in C++11? Or does it count as accessing the same object, and therefore need a lock?

curiousguy
  • 8,038
  • 2
  • 40
  • 58
celtschk
  • 19,311
  • 3
  • 39
  • 64
  • 11
    It's fine, they are two distinct locations. I'll leave someone with the energy to prove it to answer. – GManNickG Aug 18 '13 at 20:15
  • @Mat But every object/primitive in C/C++ is required to be at least 1 byte. And 1 byte is the "smallest addressable unit". – Mysticial Aug 18 '13 at 20:18
  • The answer's in there somewhere I think http://isocpp.org/blog/2013/02/atomic-weapons-the-c-memory-model-and-modern-hardware-herb-sutter – Mat Aug 18 '13 at 20:22
  • @Mat I remember hearing somewhere that the standard requires that all field members have different addresses. Although this is 3rd hand info I heard from chat. I'll wait for someone to confirm/deny it. – Mysticial Aug 18 '13 at 20:23
  • @Mat: Thanks for that interesting link. I just watched part 1; while the answer to my question wasn't in that, I learned a lot of other stuff from it. – celtschk Aug 18 '13 at 21:59
  • 4
    Note that although this is safe, it will likely result in [false sharing](http://en.wikipedia.org/wiki/False_sharing) and degrade performance. – Cory Nelson Aug 19 '13 at 00:46

1 Answers1

27

It's safe. Quoting C++11:

[intro.memory]p3:

A memory location is either an object of scalar type or a maximal sequence of adjacent bit-fields all having non-zero width. [ Note: Various features of the language, such as references and virtual functions, might involve additional memory locations that are not accessible to programs but are managed by the implementation. —end note ] Two threads of execution (1.10) can update and access separate memory locations without interfering with each other.

[intro.memory]p5:

[ Example: A structure declared as

struct {
  char a;
  int b:5,
  c:11,
  :0,
  d:8;
  struct {int ee:8;} e;
}

contains four separate memory locations: The field a and bit-fields d and e.ee are each separate memory locations, and can be modified concurrently without interfering with each other. The bit-fields b and c together constitute the fourth memory location. The bit-fields b and c cannot be concurrently modified, but b and a, for example, can be. —end example ]

These together mean that the members a and b of X are separate memory locations, and can thus be accessed concurrently.

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455