String format for intptr_t and uintptr_t

What is the string format for intptr_t and uintptr_t , which is valid for 32-bit and 64-bit architecture.

EDIT

 warning: format '%x' expects type 'unsigned int', but argument 2 has type "AAA" 

This is a warning that I get in 64 bits, but not 32 bits.

  intptr_t AAA 
+27
c formatting printf scanf
Apr 26 '11 at 20:20
source share
6 answers

These will be the following macros from inttypes.h :

For printf : PRIdPTR PRIiPTR PRIoPTR PRIuPTR PRIxPTR PRIXPTR

For scanf : SCNdPTR SCNiPTR SCNoPTR SCNuPTR SCNxPTR

Usage example:

 uintptr_t p = SOME_VALUE; printf("Here a pointer for you: %" PRIxPTR "\n", p); 
+42
Apr 26 '11 at 20:26
source share

I think you should consider using the 'Z' modifier. This converts everything that matches size_t or ssize_t, and I found that this works with (u) intptr_t as well.

For example:

intptr_t ip = ...; printf ("ip =% zd \ n", ip);

+1
Sep 17 '18 at 15:27
source share

I think that even long int unsafe, and you should try the long long int , which should exist, because you are working with 64-bit architecture, and you already have intptr_t .

In some 64-bit architectures (I think Microsoft Windows will be like this), long int can be stored in 32-bit width to satisfy the assumption of MS-DOS-age that short int always 16-bit and long int always 32-bit.

Even on those platforms with 32-bit long int , printf("%llx", (unsigned long long)AAA); will work. And you should consider the more preferred form printf("%jx", (uintmax_t)AAA); , if possible.

Note that for some older compilers you may need to use "%Lx" (for GNU C casting in unsigned long long ) or "%I64x" (for Visual C ++ casting to __uint64 ) for 64-bit integers.

P.C. %p may not be very good in this case, because %p may print bareword 0x before the hexadecimal elements and / or may print a null value. If both are used, for example, code printf("%p\n", (void*)16); will print 0x00000010 on 32-bit platforms and 0x0000000000000010 on 64-bit platforms; the poster should hope that only 10 will be printed.

0
May 26 '17 at 5:23 a.m.
source share

%p should work as a replacement for %x , since uintptr_t is defined as an unsigned integer with the same size as the pointer on the platform.

EDIT: Unfortunately, at least on my compiler you need to pass the variable to (void *). However, I think it is safe to display uintptr_t to a pointer.

-one
Jan 27 '17 at 15:16
source share

I am compiling some code in an environment that for some reason does not have the PRI.PTR macros defined in inttypes.h , and in which intptr_t is defined as int in 32 bits and long int in 64 bits.

I cracked the warnings using the %li format specifier and throwing the variables into long int in the printf options. This is safe in this environment since intptr_t never be longer than long int , as described above.

I would not recommend using this solution if you can avoid it, but it solved at least the warnings.

-2
Jan 15 '16 at 9:59
source share
 ####################################### CPP type proving code (identifying type by typeid) $ cat typeid.cpp #include <stdio.h> #include <stddef.h> #include <stdint.h> #include <time.h> #include <typeinfo> #define name(t) printf("%30s : %s\n", #t, typeid(t).name()) // g++|clang++ -o ./typeid.exe typeid.cpp -m32 && ./typeid.exe // g++|clang++ -o ./typeid.exe typeid.cpp -m64 && ./typeid.exe int main(int argc, char* argv[]) { name(ptrdiff_t); name(intptr_t); name(uintptr_t); return 0; } ####################################### C type proving code (identifying type by _Generic) $ cat typeid.c #include <stdio.h> #include <stdint.h> #include <stddef.h> #include <time.h> /* matches the type name of an expression */ #define name_match(e) _Generic((e), \ _Bool: "_Bool", \ char: "char", \ signed char: "signed char", \ unsigned char: "unsigned char", \ short: "short", \ unsigned short: "unsigned short", \ int: "int", \ unsigned int: "unsigned int", \ long: "long", \ unsigned long: "unsigned long", \ long long: "long long", \ unsigned long long: "unsigned long long", \ float: "float", \ double: "double", \ long double: "long double", \ default: "unknown") #define name(t, e) printf("%30s : %s\n", #t, name_match(e)) int main() { ptrdiff_t ptrdiff_v = 0; intptr_t intptr_v = 0; uintptr_t uintptr_v = 0; name(ptrdiff_t, ptrdiff_v); name(intptr_t, intptr_v); name(uintptr_t, uintptr_v); } ####################################### run in arch32 $ clang++ -o ./typeid.exe typeid.cpp -m32 && ./typeid.exe ptrdiff_t : i intptr_t : i uintptr_t : j $ clang -o ./typeid.exe typeid.c -m32 && ./typeid.exe ptrdiff_t : int intptr_t : int uintptr_t : unsigned int result: intptr_t == ptrdiff_t uintptr_t == unsigned ptrdiff_t ####################################### run in arch64 $ clang++ -o ./typeid.exe typeid.cpp -m64 && ./typeid.exe ptrdiff_t : l intptr_t : l uintptr_t : m $ clang -o ./typeid.exe typeid.c -m64 && ./typeid.exe ptrdiff_t : long intptr_t : long uintptr_t : unsigned long result: intptr_t == ptrdiff_t uintptr_t == unsigned ptrdiff_t ####################################### man 3 printf t -- A following integer conversion corresponds to a ptrdiff_t argument. ####################################### conclusion // intptr_t == ptrdiff_t // uintptr_t == unsigned ptrdiff_t // so: // 1) intptr_t has string format %td // 2) uintptr_t has string format %tu #include <stdio.h> #include <stdint.h> int main(int argc, char *argv[]) { intptr_t x = 0; uintptr_t y = 0; scanf("%td %tu", &x, &y); printf("out: %td %tu\n", x, y); return 0; } 
-2
Oct 31 '17 at 7:17
source share



All Articles