2011-04-26 34 views
23

intptr_tuintptr_t的字符串格式對32位和64位體系結構都有效。intptr_t和uintptr_t的字符串格式

編輯

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

這是我在64位,但不是在32位得到警告。

intptr_t AAA 

回答

36

這將是從inttypes.h以下宏:

對於printfPRIdPTR PRIiPTR PRIoPTR PRIuPTR PRIxPTR PRIXPTR

scanfSCNdPTR SCNiPTR SCNoPTR SCNuPTR SCNxPTR

+19

使用示例:'uinptr_t p = SOME_VALUE; \ n「,p);' – 2011-04-26 20:33:17

+0

感謝您的回答,我的問題可能並非如此精確......我究竟想知道是否有像*這樣的強大格式, *「%d」**爲整數等。我得到一些警告,取決於硬件架構。我編輯了我的問題。 – thetna 2011-04-26 20:33:40

-2

我編譯一些代碼的環境這對於一些原因是不是PRI.PTR宏定義在inttypes.h中,其中intptr_t定義爲32位中的int和64位中的long int

我通過使用%li格式說明符並在printf參數中將變量轉換爲long int來破解警告。這是安全的在這個環境內,因爲如上所述intptr_t永遠不會比long int更長。

如果您可以避免使用此解決方案,我不建議使用此解決方案,但至少可以解決警告。

-1

%p應該作爲%x的替代品,因爲uintptr_t被定義爲與平臺上的指針大小相同的無符號整數。

編輯:不幸的是,至少在我的編譯器中,你必須將變量轉換爲(void *)。但是,我認爲將uintptr_t強制轉換爲指針是安全的。

+0

非常不正確。 – 2017-10-31 17:07:48

0

我認爲,即使long int是不安全的,你應該嘗試long long int,必須存在,因爲你正在處理的64位架構,你有intptr_t了。

在某些64位架構(我認爲微軟的Windows會如此),long int可以保持在32位的寬度,以滿足MS-DOS時代的假設short int始終是16位和long int總是32位。

即使在那些具有32位long intprintf("%llx", (unsigned long long)AAA);的平臺上也可以工作。如果可能的話,你應該考慮更優選的形式printf("%jx", (uintmax_t)AAA);

注意,對於一些老的編譯器,你可能需要使用"%Lx"(對於GNU C,與鑄造unsigned long long)或"%I64x"(對於Visual C++,與鑄造__uint64)的64位整數。

P. S. %p在這種情況下可能不會很好,因爲%p可能會在十六進制之前打印裸字0x和/或可能會打印零填充值。例如,如果應用了這兩者,則代碼printf("%p\n", (void*)16);將在32位平臺上打印0x00000010,在64位平臺上打印0x0000000000000010;應該打印海報應該只有10

-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; 
} 
+0

抱歉,這個問題用C標記,爲什麼用cpp解決方案回答? – Stargateur 2017-10-31 07:21:53

+0

使用'#include '需要cpp後綴。據我所知,printf是C函數,而不是CPP函數,std :: printf是CPP函數。 – 2017-10-31 07:34:22

+0

@Stargateur你說這是一個cpp解決方案,只是因爲有一個cpp後綴? – 2017-10-31 07:41:10