Кресты / Говнокод #27423 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
// Приведение численного типа к структуре с битовыми полями
template <class STRUCT_T, typename T>
STRUCT_T struct_cast(const T n)
{
    static_assert(std::is_integral<T>::value, "Integral type required as T");
    static_assert(std::is_class<STRUCT_T>::value, "class or struct type required as STRUCT_T");
    static_assert(sizeof(T) == sizeof(STRUCT_T), "Incompatible types passed");

    return *(reinterpret_cast<const STRUCT_T*>(&n));
}

// Приведение структур с битовыми полями к численному типу
template <typename T, class STRUCT_T>
T integral_cast(const STRUCT_T& s)
{
    static_assert(std::is_integral<T>::value, "Integral type required as T");
    static_assert(std::is_class<STRUCT_T>::value, "class or struct type required as STRUCT_T");
    static_assert(sizeof(T) == sizeof(STRUCT_T), "Incompatible types passed");

    return *(reinterpret_cast<const T*>(&s));
}

Почему это UB?

Запостил: YpaHeLI_ YpaHeLI_, (Updated )

Комментарии (4) RSS

  • https://en.cppreference.com/w/cpp/language/reinterpret_cast
    Whenever an attempt is made to read or modify the stored value of an object of type DynamicType through a glvalue of type AliasedType, the behavior is undefined unless one of the following is true:

    AliasedType and DynamicType are similar.
    AliasedType is the (possibly cv-qualified) signed or unsigned variant of DynamicType.
    AliasedType is std::byte (since C++17), char, or unsigned char: this permits examination of the object representation of any object as an array of bytes.
    Ответить
    • > are similar.
      какой дефинишен)

      а если стрикт алайзинг отключить? или не поможет?
      Ответить
      • > какой дефинишен)
        В Стандарте есть формальное определение, просто оно (по традиции) длинное и запутанное.

        > а если стрикт алайзинг отключить?
        Поможет, просто отключатся някоторые оптимизации. Ну и код няпортабельный будет, конячно, хотя это по задаче смотреть нядо.
        Ответить
  • template <class To, class From>
    To struct_cast(const From & from)
    {
        static_assert(std::is_trivially_copyable_v<To>, "To must be trivially copyable");
        static_assert(std::is_trivially_copyable_v<From>, "From must be trivially copyable");
        static_assert(sizeof(From) == sizeof(To));
        
        To to;
        std::memcpy(std::addressof(to), std::addressof(from), sizeof(To));
        return to;
    }

    Примерня так будет по Стандарту.
    А с 20-й версии можня не городить велосипед: https://en.cppreference.com/w/cpp/numeric/bit_cast .
    Ответить

Добавить комментарий

Переведи на "PHP", guest!

    А не использовать ли нам bbcode?


    8