Sven
Sven

Reputation: 35

Int pointer type to int

I'm having hard time working around one warning issued by VS2013. What I have is a piece of code used for passing text to int var:

#define WRITE(txt)  { foo->bar.func = func_xyz; foo->bar.xyz.var = (((uint64_t) (uintptr_t) (txt)) & 0xFFFFFFFFu); } //where var is uint32_t

Which causes the compiler to return

warning C4244: '=' : conversion from 'uintptr_t' to 'uint32_t', possible loss of data.

Now unfortunately I can't possibly change var type to anything else than uint32_t and unfortunately I fall victim to preprocessor directive

#ifdef  _WIN64
    typedef unsigned __int64    uintptr_t;

Is there any way to get around this warning and do it the right way? I'm 100% sure that this is fully working (simply because it is), but any kind of warning is unacceptable.

Upvotes: 0

Views: 119

Answers (2)

John Bollinger
John Bollinger

Reputation: 181149

Is there any way to get around this warning and do it the right way?

If txt can be a pointer, and you intend to capture its value in a form from which the pointer can be recovered, then no, what you are doing is inherently wrong, and the compiler is warning you about a bona fide flaw in your code.

The type uintptr_t is an unsigned integer type wide enough to hold the value of any pointer converted to integer. In win64, pointers can be wider than 32 bits, so uintptr_t must be wider, too. (And you are not a "victim" of that -- that type is specified by the standard as having those characteristics.) There is no voodoo that can make arbitrary 64-bit values fit in 32 bits.

I'm 100% sure that this is fully working (simply because it is), but any kind of warning is unacceptable.

It may have worked in all your tests, on your particular test hardware, on your particular test scenarios, and maybe even in production. That does not mean it is correct, or that it will work reliably on other hardware, or with other inputs.

Upvotes: 2

seleciii44
seleciii44

Reputation: 1569

One more cast should do it:

#define WRITE(txt) {                                                             \
    foo->bar.func = func_xyz;                                                    \
    foo->bar.xyz.var = (uint32_t)(((uint64_t) (uintptr_t) (txt)) & 0xFFFFFFFFu); \
} //where var is uint32_t

Upvotes: 2

Related Questions