开发者

No-overflow cast on x64

I have an existing C codebase that works on x86.

I'm now compiling it for x64.

What I'd like to do is cast a size_t to a DWORD, and throw an exception if there's a loss of data.

Q: Is ther开发者_JAVA百科e an idiom for this?


Here's why I'm doing this:

A bunch of Windows APIs accept DWORDs as arguments, and the code currently assumes sizeof(DWORD)==sizeof(size_t). That assumption holds for x86, but not for x64. So when compiling for x64, passing size_t in place of a DWORD argument, generates a compile-time warning.

In virtually all of these cases the actual size is not going to exceed 2^32. But I want to code it defensively and explicitly.

This is my first x64 project, so... be gentle.


see boost::numeric_cast

http://www.boost.org/doc/libs/1_33_1/libs/numeric/conversion/doc/numeric_cast.html


I just defined a function to perform the cast.

I included an assert-like behavior to insure I'm not silently rubbishing pointers.

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


#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:

Or better yet, do this so you can use it in an 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);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜