Нужен ли этот «дополнительный» кастинг? - PullRequest
1 голос
/ 09 марта 2011

Ситуация:

typedef unsigned int u32;
typedef unsigned char u8;

const u8 *x;
...
var = (u32)(*(const u32 *)x);

var должен содержать значение размера DWORD. Что я знаю об операторе присваивания выше, так это:

  1. x - это первый указатель на размер u8 значение.
  2. x затем приводится к Значение размера u32, поэтому мы имеем: (const у32 *) х.
  3. х затем разыменовывается, в чтобы получить 32-битное значение на что оно указывает, поэтому имеем: * (const u32 *) x
  4. Данные, на которые обращаются ссылки, затем преобразуются в u32. размер.

Итак, наконец, вопрос: я думал, что в # 3 выше, разыменование скажет, что значение, которое мы получаем из него, имеет 32-битный размер, так что если это так, то почему дополнительное приведение (явное?), чтобы сказать, что разыменованное значение является 32-разрядным? Разве не было бы хорошо просто выполнить шаги с 1 по 3 выше, и не нужно делать шаг 4?

Спасибо за разъяснения!

Ответы [ 3 ]

2 голосов
/ 09 марта 2011

Да, окончательный (u32) актерский состав избыточен.

1 голос
/ 09 марта 2011

Окончательное приведение в порядке, так как вы используете его в RHS назначения.

Не в порядке оператор *.Это может дать вам двоякое неопределенное поведение:

  • вы получаете доступ к объекту за его пределами
  • char обычно выровнены иначе, чем другие целочисленные типы.
0 голосов
/ 09 марта 2011

В этом случае окончательное приведение не требуется. Следующее выражение:

(*(const u32 *)x)

возвращает значение "const u32". Поскольку вы присваиваете это переменной (которая, вероятно, является переменной u32), вы делаете копию значения «const u32», и эта копия не обязательно должна быть const. Вы сами решаете, хотите ли вы, чтобы копия, которую вы только что сделали, была постоянной или нет. Так что это действительно:

u32 var = *(const u32 *)x;

Но это также верно:

const u32 var = *(const u32 *)x;

Но в этом случае вы не можете больше изменять значение var после присваивания.

Обратите внимание, что это утверждение недопустимо:

u32 &var = *(const u32 *)x;

В этом случае вы не делаете копию, но создаете псевдоним var для содержимого переменной x, и если результатом выражения является const, ваш псевдоним также должен быть const.

Компилятор, вероятно, выдаст вам сообщение об ошибке, подобное этому:

cannot convert from 'const u32' to 'u32 &'

Вместо этого вы должны написать это:

const u32 &var = *(const u32 *)x;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...