Здравствуйте, Centaur, Вы писали:
C>Здравствуйте, mp_op, Вы писали:
_>>Подскажите пожалуйста, как корректно (по стандарту) сравнить два union`а гарантированно одинакового размера, но неизвестного содержания
C>Для начала следует определиться, что значит «объект a типа union A равен объекту b типа union B».
sizeof(u1) == sizeof(u2)
C>В общем случае это неосмысленное отношение.
Общий случай мне и не нужен. Вот еще раз пример, который я приводил, давайте отталкиваться от него.
union u1
{
int * a;
void * v;
} v1;
union u2
{
int * a;
char * b;
void * v;
} v2;
uzhas написал, про сведение к единому типу, если почитать ветку с Pavel Dvorkin, то я там как раз это и предлагаю. Только вместо int* — void*.
В юнионах всегда только указатели и всегда присутствует void*.
Мой вопрос в следующем, корректно ли по стандарту сравнивать
v1.v == v2.v
при условии, что изначально записаны в v1 был int*, а в v2 — char*?
Равносильно ли это простому приведению к типу void*? Даже чуть больше уточню, интересует сравнение на неравенство (и только).
Я знаю, что union_cast`ы запрещены. Но знаю, что любой указатель на объект в С++ можно сконвертировать в void* неявно. Нет ли тут лазейки?
C>В частном случае, когда имена и типы полей совпадают, скорее всего, понятие равенства будет выглядеть как «в обоих объектах активен один и тот же вариант И значения этих вариантов равны», для какого-нибудь набора предикатов равенства над парами каждого варианта.
В том и дело, что какой из вариантов активен — неизвестно. Нужно просто сравнить v1 и v2. Хочу узнать корректный способ. Типы полей совпадают всегда только в одном — есть void*, все остальные могут быть произвольные указатели на объекты (только указатели). Исходя из этого все мои юнионы всегда sizeof(U) == sizeof(void*), так как получается, что void* всегда самый большой член юниона (по причине конвертируемости в него всех остальных указателей).
Немного сумбурно, но вроде сейчас больше нет недомолвок. Спасибо.