These warnings are harmless (in this case) and can safely be ignored.
The warnings are coming from the casts on these lines:
printf("thread 1 return code:%d\n", (int)tret); // line 44
...
printf("thread 2 return code:%d\n", (int)tret); // line 51
The compiler is complaining that you're casting a pointer (which may be 64 bits) down into a smaller, 32-bit integer. A lot of legacy C code likes to cast back-and-forth between pointers and integers for various reasons. In the old days, pointers were the same size as integers, so this was ok; but when 64-bit targets became more common, this is dangerous all of a sudden, since if you have a 64-bit pointer pointing above the address 0x00000000'ffffffff, you'll lose the upper bits when casting it to an integer. When you cast that back to a 64-bit pointer later, your pointer will be incorrect, and attempting to use it will crash or silently corrupt memory.
The warnings here are just trying to help you avoid these potential problems. If the value in your pointer isn't actually a real pointer, like in this case, then it's perfectly safe to cast it down to an integer if you know its value is never going to exceed 0xffffffff.
There are a few ways to suppress the warning. You could disable it globally in your compiler's command line (not recommended); you could use a #pragma
around the code to temporarily disable the warning (not portable); or, you could use some clever casting to work around it.
There are two data types, intptr_t
and uintptr_t
, which act just like ordinary integers—you can upcast/downcast to other integer types, you can do all sorts of arithmetic on then, etc.—but they're guaranteed to be large enough to hold a pointer value. On a 32-bit system, intptr_t
will be (at least) 32 bits wide; on a 64-bit system, intptr_t
will be (at least) 64 bits wide. The only difference between the two types is that intptr_t
is signed while uintptr_t
is unsigned.
Since the compiler knows that these types are always large enough to hold pointer values, it won't warn you when you cast a pointer to or from them. Once you get into the integer domain, you can then cast to an ordinary int
without fear of warnings. So this code should eliminate your warnings:
#include <stdint.h>
...
printf("thread 1 return code:%d\n", (int)(intptr_t)tret); // line 44
printf("thread 2 return code:%d\n", (int)(intptr_t)tret); // line 51