intptr_t和uintptr_t的字符串格式

时间:2011-04-26 20:20:26

标签: c formatting printf scanf

intptr_t uintptr_t的字符串格式是什么,它对32位和64位架构都有效。

修改

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

这是我在64位但不是32位的警告。

  intptr_t  AAA

6 个答案:

答案 0 :(得分:43)

这将是来自inttypes.h的以下宏:

printfPRIdPTR PRIiPTR PRIoPTR PRIuPTR PRIxPTR PRIXPTR

scanfSCNdPTR SCNiPTR SCNoPTR SCNuPTR SCNxPTR

用法示例:

uintptr_t p = SOME_VALUE;
printf("Here's a pointer for you: %" PRIxPTR "\n", p);

答案 1 :(得分:1)

我认为您应该考虑使用'z'修饰符。这将转换与size_t或ssize_t对应的任何内容,我发现它也可以与(u)intptr_t一起使用。

例如:

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

答案 2 :(得分:0)

%p应该作为%x的替代,因为uintptr_t被定义为无符号整数,其大小与平台上的指针相同。

编辑:不幸的是,至少在我的编译器上你必须将变量强制转换为(void *)。但是,我认为将uintptr_t转换为指针是安全的。

答案 3 :(得分:0)

我认为即使long int是不安全的,您也应该尝试long long int,这必须存在,因为您正在使用64位架构并且已经intptr_t

在某些64位体系结构上(我认为Microsoft Windows会如此),long int可以保持32位宽度,以满足MS-DOS时代假设short int总是如此16位且long int始终为32位。

即使在具有32位long int的平台上,printf("%llx", (unsigned long long)AAA);也可以。如果可能的话,你应该考虑更优选的printf("%jx", (uintmax_t)AAA);形式。

请注意,对于某些旧编译器,您可能需要使用"%Lx"(对于GNU C,使用强制转换为unsigned long long)或"%I64x"(对于Visual C ++,使用强制转换为{{1}对于64位整数。

P上。 S. __uint64在这种情况下可能不太好,因为%p可能会在十六进制之前打印裸字%p和/或可能会打印零填充值。例如,如果应用了这两者,代码0x将在32位平台上打印printf("%p\n", (void*)16);,在64位平台上打印0x00000010;海报应该希望只打印0x0000000000000010

答案 4 :(得分:-2)

我正在一个环境中编译一些代码,因为某些原因,PRI.PTR中定义了inttypes.h个宏,其中intptr_t是在32位中定义为int,在64位中定义为long int

我通过使用%li格式说明符并将变量转换为long int参数中的printf来解决警告问题。这在此环境中是安全的,因为intptr_t永远不会超过long int,如上所述。

如果您可以避免使用此解决方案,我建议不要使用此解决方案,但它至少解决了警告。

答案 5 :(得分:-2)

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