2016-10-06 4 views
1

Иногда компиляторы C++ генерируют разные макеты памяти для одного и того же типа T в одном и том же двоичном файле. А именно, это происходит, когда объекты возникают как в несмежном подобъект класса, а в качестве отдельного объекта или массива подобъекта:Различные макеты для одного и того же типа в одном двоичном файле

struct A { int i; }; 
struct B : virtual A { int i; }; 
struct C : virtual A { int i; }; 
struct D : B,C { int i; }; 
... 
D d; 
B b; 
B* p1= &(B&)d; 
B* p2= &b; 

В соответствии с С ++ 14 стандартного, это компилятор свободно генерировать любой количество различных макетов для объектов типа T в одном бинарном файле? Являются ли макеты памяти фиксированными во время компиляции?

Выделения: How does placement new know which layout to create?


Разработка на второй вопрос: Объект т типа Т могут быть доступны либо Т *, либо символ * указателей. (Последнее оправдано §3.10 (10)). После того как скомпилированная программа запущена, можно определить относительные смещения подобъектов t, обратившись к t через указатели char. Являются ли эти смещения детерминированными или могут ли они меняться от одного выполнения программы к другому?

+0

Не могли бы вы рассказать о своем вопросе? Что вы подразумеваете под * Являются ли макеты памяти фиксированными во время компиляции *? –

ответ

2

Согласно стандарту C++ 14 вы получаете UB, если вы конвертируете указатель в класс, указатель на что-то еще, а затем используйте указатель. Таким образом, вы не можете получить смещение от начала класса, а затем добавить его указатель класса.

Для стандартных объектов макета вы получаете больше гарантий, и вы можете использовать offsetof и получать детерминированные результаты. Классы с виртуальным наследованием сложны и определенно не являются стандартными макетами.

+0

Не могли бы вы предоставить цитаты, подтверждающие ваши претензии UB, пожалуйста? Хотя есть некоторые приведения, которые приводят к UB, я считаю, что это нормально. ((char *) (void *) & t) –

+0

Литье в порядке. Вам разрешено указывать любой указатель на любой (примечание: в визуальных указателях студии к классам классов с виртуальным наследованием больше). Но единственное, что вам разрешено делать с таким литым указателем, - это скопировать его или вернуть его в исходный тип. UB не находится в указателях кастингов, а в предположениях о макете класса, которая является детализацией реализации. –

+0

Вы имеете в виду UB = undefined или unspecified?Теперь запись случайных случайных чисел в файл явно не определена, и писать необработанную память не так. (В стандарте очень ясно, что речь идет о недетерминированной абстрактной машине). Я не вижу, где это будет деградировать в неопределенное поведение, которое приведет к недействительности всей программы. Стандарт указывает, что означает * p для указателя char p. (§5.3.1.1, §3.10.10) –

0

Предварительный ответ (В настоящее время, не принимайте это как должное):

Предположим, T является типом класса, по крайней мере, двух нестатические элементов данных. Если T не является стандартным классом макета, допустим, что два элемента данных являются общедоступными и частными, имея различный контроль доступа. Понятно, что описанные ниже схемы соответствуют требованиям к порядку и смежности, установленным стандартом.

a) Если T не является ни тривиально копируемой, ни стандартной компоновкой, реализация может использовать генератор случайных чисел для создания нового макета памяти при создании объекта типа T. Не существует верхнего предела для количества различных макетов памяти для T, которые могут быть созданы одним двоичным кодом. (Нет ничего противоположного в стандарте, действительно? Должно быть, что-то не хватает)

b) Если T является тривиально копируемой, но не стандартной компоновкой, реализация может использовать генератор случайных чисел при запуске программы для создания макета для T. Количество возможных макетов конечно. Макеты могут отличаться от одного исполнения программы до следующего. (ограничения, связанные с пп. 9.2.2 и п. 1.8.5)

c) Если T является стандартным макетом, существует только один возможный макет. (Гарантирован порядок и соприкосновение)

Смежные вопросы