The following line (pure c) compiles cleanly on windows (win7 64 bits + codeblocks 13 + mingw32) and debian (wheezy 32 bits + codeblocks 10 + gcc) but raises warning on kali (64 bits + codeblocks + gcc). Any comments? I mean, why do I get this warning, though the same line compiles w/o any warning on windows & debian?
void* foo(void *dst, ...) {
// some code
unsigned int blkLen = sizeof(int); // this line ok.
unsigned int offset = (unsigned int) dst % blkLen; // warning here!
// some code cont...
}
The message in codeblocks is: "error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast]"
note: my compiler options are -std=c99 -Werror -save-temps
(same on all three systems).
edit 2:
Though I've managed to have it compiled w/o warning using the preprocessor lines below,
@Keith Thompson (see below) has a crucial point about the issue. So, my last decision is using uintptr_t
would be a better choice.
edit 1: Thanks for everyone replied. As all the replies note, the problem is a 32 bits vs 64 bits issue. I've inserted following preprocessor lines:
#if __linux__ // or #if __GNUC__
#if __x86_64__ || __ppc64__
#define ENVIRONMENT64
#else
#define ENVIRONMENT32
#endif
#else
#if _WIN32
#define ENVIRONMENT32
#else
#define ENVIRONMENT64
#endif
#endif // __linux__
#ifdef ENVIRONMENT64
#define MAX_BLOCK_SIZE unsigned long long int
#else
#define MAX_BLOCK_SIZE unsigned long int
#endif // ENVIRONMENT64
and then replaced the problem line as:
unsigned int offset = (MAX_BLOCK_SIZE) dst % blkLen;
Now, everything seems OK.
Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined. If the result cannot be represented in the integer type, the behavior is undefined. The result need not be in the range of values of any integer type.
You're return ing the value of int sum by setting a void * address to it. In this case, the address is not valid. But, if you keep that in mind and get the value of sum by casting a void * to int it will work.
Casting a pointer to a different pointer and back is usually safe and yields the original value. The limitations are that object pointers can be cast only to object pointers with similar or stricter alignment requirements, and function pointers can be cast only to function pointers.
reinterpret_cast converts any pointer type to any other pointer type, even of unrelated classes. The operation result is a simple binary copy of the value from one pointer to the other.
The reason for the warning is that the compiler suspects you might be trying to round-trip a pointer through int
and back. This was common practice before the advent of 64-bit machines and it is not safe or reasonable. Of course here the compiler can clearly see that you're not doing this, and it would be nice if it were smart enough to avoid the warning in cases like this, but it's not.
A clean alternative that avoids the warning, and another much nastier issue of wrong result when the converted value is negative, is:
unsigned int offset = (uintptr_t) dst % blkLen;
You'll need to include stdint.h
or inttypes.h
to have uintptr_t
available.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With