пятница, 26 января 2024 г.

[prog.c++] Интересное чтиво про strict aliasing rule...

...лежит здесь: What is the Strict Aliasing Rule and Why do we care?

Документ далеко не новый, но если вы не в теме, то он будет, безусловно, полезен.

Из того, что стало откровением и открытием лично для меня (применительно к C++):

  • в C++ содержимое другого объекта можно просматривать путем каста к char, unsigned char или std::byte. Т.е., грубо говоря, вы всегда можете сделать reinterpret_cast<char *>(other_pointer). Но это не распространяется на signed char. И отдельная история с std::int8_t/uint8_t: эти типы могут быть простыми синонимами для char и unsigned char, а могут быть и отдельными, самостоятельными типами (в таком случае на них правило char/unsigned char/std::byte не распространяется);
  • оказывается, современные компиляторы могут понять, что делает std::memcpy и избавиться от реального вызова std::memcpy. Например, вот такой корректный способ получить float из int-а (при условии их одинаковых размеров):

    int src = ...;
    float dst;
    std::memcpy(&dst, &src, sizeof(src));

    в случае умного компилятора будет просто помещать в dst нужно значение без вызова memcpy;

  • не знал раньше про common initial sequence. А это, как выяснилось, может стать архиважной штукой при работе с union:

    struct A { char type; ... };
    struct B { char type; ... };
    struct C { char type; ... };
    union U { A a; B b; C c; };
    
    U u;
    u.a = ...;
    if(u.b.type == ...) // (1)
    {...}

    Обращение к u.b в точке (1) легально не смотря на то, что U::b -- это неактивный в данный момент элемент union-а.

Комментариев нет: