2010-05-29 5 views
1

J'ai une base de code C existante qui fonctionne sur x86.No-overflow cast sur x64

Je compile maintenant pour x64. Qu'est-ce que je voudrais faire est de lancer un size_t à un DWORD, et de jeter une exception en cas de perte de données.

Q: Existe-t-il un idiome pour cela?


Voici pourquoi je fais ceci:

Un groupe d'API Windows acceptent DWORDs comme arguments, et le code prend actuellement sizeof (DWORD) == sizeof (size_t). Cette hypothèse est valable pour x86, mais pas pour x64. Ainsi, lors de la compilation pour x64, en passant size_t à la place d'un argument DWORD, génère un avertissement à la compilation.

Dans pratiquement tous ces cas, la taille réelle ne dépassera pas 2^32. Mais je veux le coder de façon défensive et explicite.

Ceci est mon premier projet x64, alors ... soyez gentil.

Répondre

0

Je viens de définir une fonction pour effectuer la distribution.

J'ai inclus un comportement semblable à un assert pour m'assurer que je ne détruis pas silencieusement les pointeurs.

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; 
} 
0
#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:

Ou mieux encore, faire de sorte que vous pouvez l'utiliser dans une expression:

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); 
}