Russian Qt Forum

Программирование => С/C++ => Тема начата: TheBlade от Мая 24, 2010, 16:59



Название: (ТИП) или static_cast<ТИП>()
Отправлено: TheBlade от Мая 24, 2010, 16:59
Код:
struct Rez_10_A2
{
 short CMD;
 ...
 short KS;
};

union SEND
{
short buf[200];
        ...
struct Rez_10_A2   R10A2;
        ...
};

Есть строка (SEND *)file.read(sizeof(Rez_10_A2)).data()
Но как я понимаю преобразование (SEND *) не является безопасным.
Подскажите пожалуйста, можно ли использовать какой-нибудь static_cast и как ?
Очень надеюсь на вашу помощь.


Название: Re: (ТИП) или static_cast<ТИП>()
Отправлено: Alex Custov от Мая 25, 2010, 23:58
В данном случае надо использовать reinterpret_cast<>, т.к. преобразовываются несовместимые типы


Название: Re: (ТИП) или static_cast<ТИП>()
Отправлено: Amigo_sa от Мая 26, 2010, 10:07
static_cast используется в случае 1) приведения стандартных типов, которые можно привести к void 2) для приведения указателей классов в иерархии наследования.
reinterpret_cast не выполняет никаких проверок при выполнении, говорит компилятору считать такой то объект таким то типом. Очень опасное преобразование.


Название: Re: (ТИП) или static_cast<ТИП>()
Отправлено: sne от Мая 26, 2010, 11:03
Ну тут как бы без особых вариантов, либо сишный каст, либо reinterpret. Только обязательно нужно убедиться что размер полученных данных совпадает с sizeof структуры, а так же что выравнивание совпадает/отключено.


Название: Re: (ТИП) или static_cast<ТИП>()
Отправлено: spectre71 от Мая 26, 2010, 11:21
Код:
struct Rez_10_A2
{
 short CMD;
 ...
 short KS;
};

union SEND
{
short buf[200];
        ...
struct Rez_10_A2   R10A2;
        ...
};

Есть строка (SEND *)file.read(sizeof(Rez_10_A2)).data()
Но как я понимаю преобразование (SEND *) не является безопасным.
Подскажите пожалуйста, можно ли использовать какой-нибудь static_cast и как ?
Очень надеюсь на вашу помощь.


(SEND *)file.read(sizeof(Rez_10_A2)).data();
// на следующей строке QByteArray - уже уничтожен и ваша структура не валидна

С какой стати sizeof(Rez_10_A2) ?
Нужен sizeof(SEND) !

Так лучше:
Код:
SEND s;
file.read((char*)&s, sizeof(SEND));


Название: Re: (ТИП) или static_cast<ТИП>()
Отправлено: Igors от Мая 26, 2010, 12:20
По любому преобразования "опасны" и применимы только для C структур (без виртуалов). Ладно, но тогда лучше следовать замыслу автора - как я понял. именно для этого он сделал union

Код
C++ (Qt)
SEND theSend;
file.read(theSend.buf, sizeof(Rez_10_A2));
 


Название: Re: (ТИП) или static_cast<ТИП>()
Отправлено: spectre71 от Мая 26, 2010, 12:44
По любому преобразования "опасны" и применимы только для C структур (без виртуалов). Ладно, но тогда лучше следовать замыслу автора - как я понял. именно для этого он сделал union

Код
C++ (Qt)
SEND theSend;
file.read(theSend.buf, sizeof(Rez_10_A2));
 

Не верно. Есть такие штуки как выравнивание данных.
Не говоря уж о том что в общем случае не известно кто больше  sizeof(theSend.buf) или sizeof(theSend.R10A2) или еще кто в этом union
Если уж пишем SEND, то и читаем SEND. А потом уж как положено обращаемся к его элементам.


Название: Re: (ТИП) или static_cast<ТИП>()
Отправлено: Alex Custov от Мая 26, 2010, 13:08
Очень опасное преобразование.

преобразование бинарного потока в тип - всегда опасное преобразование, тут разницы особой нет - сишный каст или reinterpret_cast<>


Название: Re: (ТИП) или static_cast<ТИП>()
Отправлено: Igors от Мая 26, 2010, 13:44
Не верно. Есть такие штуки как выравнивание данных.
Не говоря уж о том что в общем случае не известно кто больше  sizeof(theSend.buf) или sizeof(theSend.R10A2) или еще кто в этом union
Если уж пишем SEND, то и читаем SEND. А потом уж как положено обращаемся к его элементам.

Разумеется. что пишем - то и читаем, по размеру должно сбиваться. Но откуда Вы взяли что пишется SEND? Почему нельзя читать/писать Rez_10_A2? Что если sizeof(theSend.R10A2) напр всего лишь 8? Зачем тогда писать 400 байт вместо 16? Будет мусор в хвосте структуры? Так с этим человек уже согласился объявив 200 "от фонаря"  :) 

Недосмотрел что buf объявлен short, надо привести к char
Код
C++ (Qt)
SEND theSend;
file.read((char *) theSend.buf, sizeof(Rez_10_A2));
 

Через sizeof(SEND) тоже можно, но тогда надо его объявлять так
Код
C++ (Qt)
union SEND
{
short buf[1];
       ...
struct Rez_10_A2   R10A2;
       ...
};
 
Здесь видно что buf явная подстава


Название: Re: (ТИП) или static_cast<ТИП>()
Отправлено: spectre71 от Мая 26, 2010, 16:46
Разумеется. что пишем - то и читаем, по размеру должно сбиваться. Но откуда Вы взяли что пишется SEND?

Вот почему:

Есть строка (SEND *)file.read(sizeof(Rez_10_A2)).data()

Иначе нет смысла использовать SEND, а сразу писать и читать только Rez_10_A2.
Либо то, либо другое, но никак не промежуточный вариант.