В C ++ 17 есть нормативный текст [class.mem] / 17:
Non-stati c членов данных (не объединяющего) класса с одинаковым контролем доступа (Раздел 14) распределяются так, чтобы более поздние члены имели более высокие адреса в объекте класса. Порядок распределения незаполненных c элементов данных с различным контролем доступа не указан.
Также имеется [class.mem] / 24:
Если у объекта класса стандартной компоновки есть любые нестатические c члены данных, его адрес совпадает с адресом его первого нестатического c члена данных
Вот два примера:
struct A { int x, y, z; } a;
struct F { public: int p; private: int q; public: int r; } f;
В соответствии с приведенным выше стандартным текстом, C ++ 17 гарантированно &a.x < &a.y
, &a.y < &a.z
и &f.p < &f.r
(но НЕ гарантирует &f.p < &f.q
, поскольку F
не является стандартным макет, так что class.mem / 24 не применяется).
Однако в окончательном рабочем проекте C4820 N4860 произошли изменения согласно CWG 2404 . [Class.mem] / 17 превратился в примечание. Тем не менее, примечания являются ненормативными в стандартах ISO (то есть поставщик компилятора может их игнорировать). И я не могу найти какой-либо другой текст, который может быть применим.
Мой вопрос: C ++ 20 еще где-то указывает (нормативно) гарантии &a.y < &a.z
и / или &f.p < &f.r
? Или у компилятора теперь есть лицензия на изменение порядка членов класса во всех случаях, кроме первого подобъекта класса стандартной компоновки?
Предполагается, что дальнейших изменений между N4860 и опубликованным стандартом не будет.