Снимает ли C ++ 20 требование, чтобы члены класса были в порядке возрастания? - PullRequest
34 голосов
/ 04 мая 2020

В 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 и опубликованным стандартом не будет.

1 Ответ

23 голосов
/ 04 мая 2020

Это все еще гарантируется [expr.rel] / (4.2) , описывающим поведение встроенных выражений <, <=, > и >= для указателя значения.

Если два указателя указывают на разные нестатические c элементы данных одного и того же объекта или субобъекты таких элементов, рекурсивно, для сравнения требуется указатель на объявленный позже элемент больше, если два члена имеют одинаковый контроль доступа ([class.access]), ни один из них не является подобъектом нулевого размера и их класс не является объединением.

...