Без перелива на x64 - PullRequest
       10

Без перелива на x64

1 голос
/ 30 мая 2010

У меня есть существующая кодовая база C, которая работает на x86.

Я сейчас собираю его для x64.

То, что я хотел бы сделать, это привести size_t к DWORD и выдать исключение в случае потери данных.

Q : Есть идиома для этого?


Вот почему я делаю это:

Группа API-интерфейсов Windows принимает DWORD в качестве аргументов, и в настоящее время код принимает sizeof (DWORD) == sizeof (size_t). Это предположение верно для x86, но не для x64. Поэтому при компиляции для x64, передавая size_t вместо аргумента DWORD, генерируется предупреждение во время компиляции.

Практически во всех этих случаях фактический размер не будет превышать 2 ^ 32. Но я хочу кодировать это в обороне и явно.

Это мой первый проект x64, так что ... будьте осторожны.

Ответы [ 3 ]

1 голос
/ 30 мая 2010
0 голосов
/ 20 августа 2011
#define size_t_to_DWORD(st,dw)  if ((DWORD)(st) != st)  RaiseException(exLossOfData, 0, 0, NULL); else dw = (DWORD)(st)

size_t  st;
DWORD   dw;
st = 0xffffffff;
size_t_to_DWORD(st,dw);  // this succeeds
st = 0xffffffff1;
size_t_to_DWORD(st,dw);  // this throws

EDIT:

Или, еще лучше, сделайте это, чтобы использовать его в выражении:

DWORD MyRaiseException()
{
    RaiseException(1, 0, 0, NULL);
    return 0;
}


#define size_t_to_DWORD(st)  (DWORD)(st) != (st) ? MyRaiseException() : (DWORD)(st)


void main(void)
{
    size_t  st;
    DWORD   dw;
    st = 0xffffffff1;
    dw = size_t_to_DWORD(st);
    printf("%u %u\n", st, dw);
}
0 голосов
/ 20 августа 2011

Я только что определил функцию для выполнения приведения.

Я включил поведение, похожее на assert, чтобы гарантировать, что я не буду молчаливо копать указатели.

DWORD ConvertSizeTo32bits(size_t sz, char *file, int line) 
{
    if (!(0 <= sz && sz <= INT32_MAX)) {
        EmitLogMessage("Invalid Pointer size: %d file(%s) line(%d)",
                       sz, file, line);

        ExitProcess( 0 );  
    }
    return (DWORD) sz;
}
...