почему union (int) выводит только только часть (char)

union c
{
    int in;
    char ch;
};
c un;
un.in = 6;
un.ch = '4';

std::cout <<un.in<< std::endl; //выведет 52

Почему выведется 52? Ведь мы изначально записали в объединение число 6 ,а потом 4(char) и получается у нас 1 байт должен содержать число 52(0x34) а остальные 3 байта остаток от того что мы записывали туда заранее 6(int),то есть теперь в объединении должно содержаться число 0x34'00'00'06


Ответы (2 шт):

Автор решения: dIm0n

Здесь у вас неопределенное поведение, потому что вы читаете из члена юниона, который был записан НЕ последним. Если убрать последнюю запись, то всё будет ок:

#include <iostream>
#include <ostream>

union c
{
    int in;
    char ch;
};

int main() {
    c un;
    un.in = 6;
    // un.ch = '4';

    std::cout <<un.in<< std::endl; //выведет 6
}

Либо читайте последнюю запись, соответственно:

#include <iostream>
#include <ostream>
    
union c
{
    int in;
    char ch;
};
    
int main() {
    c un;
    un.in = 6;
    un.ch = '4';
   
    std::cout <<un.ch<< std::endl; //выведет 4
}

А вообще, в C++ лучше использовать std::variant:

#include <iostream>
#include <variant>
    
int main() {
    std::variant<int, char> c;
    c = 6;
    c = '4';
   
    std::cout << std::get<char>(c) << '\n'; // OK
    // std::cout << std::get<int>(c) << '\n'; // исключение
}
→ Ссылка
Автор решения: Harry

Потому что младший байт идет на вашей платформе первым, а не последним... И когда вы записали число 6 - то оно легло так:

0x06  0x00  0x00  0x00

а после того, как записали '4' -

0x34  0x00  0x00  0x00

Вот оно и выводит вам ваше 52, как просили :)

Вот, посмотрите, как это все работает: https://ideone.com/tUFgBX

А вообще-то, если я не ошибаюсь, то считается, что записывать в union одно поле , а читать другое - строго говоря, UB. Хотя на практике все обычно работает - если понимать, что делаешь...

"По-моему, так" (с) Пух

→ Ссылка