переменные несовместимой ширины - PullRequest
0 голосов
/ 09 мая 2011

Я использую следующий код для упрощения присвоения больших значений определенным местам в памяти:

int buffer_address =  virtual_to_physical(malloc(BUFFER_SIZE));
    unsigned long int ring_slot = buffer_address << 32 | BUFFER_SIZE;

Однако компилятор жалуется на «предупреждение: счетчик смещения влево> = ширина типа». Но беззнаковое длинное int в C равно 64 битам, поэтому сдвиг битов (32 бита) влево на 32 бита должен дать 64-битное значение, и, следовательно, компилятор не должен жаловаться. Но это так.

Есть ли что-то очевидное, что я упускаю, или в противном случае есть простой обходной путь?

Ответы [ 3 ]

2 голосов
/ 09 мая 2011

Значение unsigned long int не обязательно 64-битное, но для простоты предположим, что оно есть.

buffer_address имеет тип int.Любое выражение без "более высоких" типов в buffer_address должно возвращать int.Таким образом, buffer_address << 32 должно возвращать int, а не unsigned long.Таким образом, компилятор жалуется.

Это должно решить вашу проблему, хотя:

unsigned long ring_slot = ((unsigned long) buffer_address) << 32 | BUFFER_SIZE;

Обратите внимание, unsigned long это не обязательно 64 бит, этозависит от реализации.Используйте это вместо:

#include <stdint.h> // introduced in C99

uint64_t ring_slot = ((uint64_t) buffer_address) << 32 | BUFFER_SIZE;
2 голосов
/ 09 мая 2011

buffer_address является (32-разрядным) int, поэтому buffer_size << 32 смещает его на величину, большую или равную его размеру.

unsigned long ring_slot = ((unsigned long) buffer_address << 32) | BUFFER_SIZE:

Обратите внимание, что «unsigned long» не обязательно должен быть 64-разрядным (он не в Windows - 32-разрядный (ILP32) или 64-разрядный (LLP64); он также не применяется на 32-разрядной машине Unix (ILP32)) , Чтобы получить гарантированное (как минимум) 64-битное целое число, вам нужно unsigned long long.

Есть несколько машин, где int - это 64-битное количество (ILP64); DEC Alpha был одним из таких, и я полагаю, что некоторые машины Cray также использовали это (и Cray также использовал «большие» типы char - более 8 бит на char).

0 голосов
/ 09 мая 2011

Результат выражения справа от знака = не зависит от того, для чего он назначен. Сначала вы должны привести к беззнаковому длинному.

unsigned long int ring_slot = (unsigned long)buffer_address << 32 | BUFFER_SIZE;
...