4

This question here indicates that std::atomic<T> is generally supposed to have the same size as T, and indeed that seems to be the case for gcc, clang, and msvc on x86, x64, and ARM.

In an implementation where std::atomic<T> is always lock free for some type T, is it's memory layout guaranteed to be the same as the memory layout of T? Are there any additional special requirements imposed by std::atomic, such as alignment?

curiousguy
  • 8,038
  • 2
  • 40
  • 58
Alecto Irene Perez
  • 10,321
  • 23
  • 46

2 Answers2

6

Upon reviewing [atomics.types.generic], which the answer you linked quotes in part, the only remark regarding alignment is the note which you saw before:

Note: The representation of an atomic specialization need not have the same size as its corresponding argument type. Specializations should have the same size whenever possible, as this reduces the effort required to port existing code

In a newer version:

The representation of an atomic specialization need not have the same size and alignment requirement as its corresponding argument type.

Moreover, at least one architecture, IA64, gives a requirement for atomic behavior of instructions such as cmpxchg.acq, which indicates that it's likely that a compiler targeting IA64 may need to align atomic types differently than non-atomic types, even in the absence of a lock.

Furthermore, the use of a compiler feature such as packed structs will cause alignment to differ between atomic and non-atomic variants. Consider the following example:

#include <atomic>
#include <iostream>
struct __attribute__ ((packed)) atom{
    char a;
    std::atomic_long b;
};
struct __attribute__ ((packed)) nonatom{
    char a;
    long b;
};

atom atom1;
nonatom nonatom1;
int disp_aligns(int num) {
    std::cout<< alignof(atom1.b) << std::endl;
    std::cout<< alignof(nonatom1.b) << std::endl;
}

On at least one configuration, the alignment of atom1.b will be on an 8-byte boundary, while the alignment of nonatom1.b will be on a 1-byte boundary. However, this is under the supposition that we requested that the structs be packed; it's not clear whether you are interested in this case.

nanofarad
  • 40,330
  • 4
  • 86
  • 117
  • The paragraph was updated with [this commit](https://github.com/cplusplus/draft/commit/3ba8b56c0ffa84cf8fe7bf78234fb8694d4d1498). – wally May 01 '19 at 22:59
4

From the standard:

The representation of an atomic specialization need not have the same size and alignment requirement as its corresponding argument type.

So the answer, at least for now, is no, it is not guaranteed to be the same size, nor have same alignment. But it might have, unless it doesn't and then it won't.

wally
  • 10,717
  • 5
  • 39
  • 72
  • Do note that what you quoted is a note and those are non-normative. Since this isn't a language lawyer Q though it should be fine. – NathanOliver May 01 '19 at 22:57
  • @NathanOliver But the note just emphasizes what is the case anyway, just to exclude the wrong idea people might have that `atomic` is guaranteed to be just an extraneous tag or so. I don't think that the standard makes any assumptions of the layout of different types (with some exceptions for aggregates). The note states nothing new. – Peter - Reinstate Monica May 01 '19 at 23:15
  • @NathanOliver What normativity can exist for a non-requirement? – curiousguy May 28 '19 at 23:54