Не могу понять, как.
Он не может использовать дополнительное пространство для другого объекта, потому что объекты не перекрываются в памяти, если один не является подобъектом другого.
Кроме того, он вообще не может использовать дополнительное пространство, если вы могли бы в любой момент написать самый большой член объединения.
В таком коде:
{
union { char c; double d; } x;
x.c = 1;
int y;
some_function(&y);
std::cout << x.c;
}
Я полагаю, что по правилу «как если бы» компилятор мог уменьшить стек, используемый для x
, до 1 байта и использовать память сразу после этого для y
.Поскольку адрес x
никогда не берется, соответствующая программа не может «наблюдать» разницу, поэтому она действительна.
Не уверен, что вы именно это имели в виду, посколькуиспользование этого союза x
окружено множеством ограничений, чтобы сделать это действительным.Это не столько случай обнаружения того, в какой момент времени остаток объединения не используется, а обнаружение того, что во всех точках остаток не используется.
Вы можете подумать, что такая же оптимизация могла бы применятьсяздесь:
{
union { char c; double d; } x;
x.c = 1;
int y;
some_function(&y);
std::cout << x.c;
x.d = 1.0;
std::cout << x.d;
}
но что если some_function
сохранит копию указателя на y
, возможно, в глобальном?Затем, если перегруженный operator<<
может в итоге косвенно вызвать любой код, использующий этот указатель, компилятор не может перезаписать память.Я сомневаюсь, что любая реализация может быть полностью встроенной std::cout << x.d
, поэтому даже если этого не произойдет, компилятор не узнает, что это не так, и не сможет выполнить оптимизацию.
Длядействительно огромный союз, охватывающий несколько страниц ОЗУ, я думаю, что теоретически физическая ОЗУ для более поздних страниц может быть освобождена при написании небольшого члена союза и повторно отображена обратно по требованию.Вряд ли стоит оправдывать реализацию, хотя, учитывая, что это будет очень редкий случай, и не намного лучше, чем обычное использование файла подкачки.