Скажем, у меня есть следующие типы:переинтерпретировать литье указатели на типы стандартных макетов с общими префиксами
struct Common { int a, b, c; };
struct Full { int a, b, c; uint64_t x, y, z; };
Common
и Full
типы стандартных макетов, где Common
является префиксом Full
. Так что, если я ставлю как в союз:
union U {
Common c;
Full f;
};
Я бы позволил прочитать c
даже если f
был активным членом в [class.mem]/23.
Теперь вопрос в том, есть ли способ для меня, учитывая Full const*
, чтобы получить Common const*
в не-UB-способе?
void foo(Full const* f) {
Common c1;
memcpy(&c1, f, sizeof(c1)); // this obviously works, but I don't want
// to be copying all this stuff
auto c2 = reinterpret_cast<Common const*>(f); // is this ok?
// c2 and f are pointer-interconvertible iff f comes from a U
// but why does that U actually need to exist?
auto u = reinterpret_cast<U const*>(f); // ok per basic.lval/8.6??
auto c3 = &u->c; // ok per class.mem/23??
}
«pointer-interconvertible» - это свойство объектов, а не типов. Если нет объединения, то результат 'reinterpret_cast' по-прежнему указывает на' * f'. –
@ T.C. Да, но разве не странно требовать нерелевантного объекта неуместного типа? – Barry
Не совсем - это исключение для системы типов, которая существует только для совместимости с C. Напомним, что P0137R0 вне закона вне закона вне закона. –