Страницы

Поиск по вопросам

воскресенье, 15 декабря 2019 г.

Доступ к структуре через unsigned char

#cpp #language_lawyer


Пусть есть структура S следующего вида:

    struct S 
    {
        short a;
        char b;
    };


И размер sizeof(short) равен 2, а размер sizeof(S) равен 4 (т.е. в структуре есть
один padding byte).

Вопрос 1. Является ли корректным с точки зрения стандарта языка такой код:

    S st;

    st.a = 0; st.b = 0;
    unsigned char *p = reinterpret_cast(&st);
    for (size_t i = 0; i != sizeof(st); ++i)
        unsigned int tmp = p[i];


Вопрос 2. Если код корректен, то гарантируется ли, что в ситуации, когда указатель
p указывает на padding byte структуры S, в переменную tmp будет записано некоторое
целочисленное значение из отрезка [0; UCHAR_MAX] или допускаются какое-нибудь менее
очевидное поведение, например, генерация исключения.



Дополнение.   

Действительно, если есть объект тривиально-копируемого типа T, то составляющие его
байты могут быть безопасно скопированы (например, с помощью memcpy) в массив char,
unsigned char или std::byte (и обратно). Также можно скопировать некоторый объект тривиально-копируемого
типа в другой объект этого же типа (с помощью того же самого memcpy, например.)

Однако, в пункте 11.6/12 (n4659) есть занятный пример:

    unsigned char c;
    unsigned char d = c; // OK, d has an indeterminate value
    int e = d; // undefined behavior


Не является ли мой пример, в некотором смысле, эквивалентом этого примера из стандарта?
    


Ответы

Ответ 1



1) Да, каст к char* и unsigned char* разрешен (а каст к другим типам запрещен правилами aliasing) 2) Нет для int. Паддинг можно читать-писать (иначе memcpy сломался бы). Однако, стандарт разрешает читать indeterminate value типа [unsigned] char в присваиваниях где левая стророна это l-value типа [unsigned] char, но запрещает присваивать например int. (При этом неясно, считается ли что паддинг может иметь indeterminate value)

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

Отправить комментарий