[英]Strange typedef for std::ptrdiff_t and std::size_t
類型std::size_t
是一個無符號類型,可以存儲任何類型的理論上可能的對象的最大大小,而std::ptrdiff_t
是一個可以保存兩個指針差異的有符號類型(這是另一種說法它應該是C ++中數組索引的標准整數)。 C ++標准庫決定使用std::size_t
進行數組索引,但經常聲明std::ptrdiff_t
是更好的選擇。 哪一個是最好的是一個長期的辯論,我不想進入這里,但我一直認為第二個是第一個的未簽名版本。 在macOS上運行此程序
#include <cstddef>
#include <cstdio>
void f(int n) { std::printf("int"); };
void f(long n) { std::printf("long"); };
void f(long long n) { std::printf("long long"); };
void f(unsigned int n) { std::printf("unsigned int"); };
void f(unsigned long n) { std::printf("unsigned long"); };
void f(unsigned long long n) { std::printf("unsigned long long"); };
int main() {
const std::ptrdiff_t n_ptrdiff = 0;
const std::size_t n_size = 0;
std::printf("std::ptrdiff_t is an alias for ");
f(n_ptrdiff);
std::printf("\n");
std::printf("std::size_t is an alias for ");
f(n_size);
std::printf("\n");
return 0;
}
在64位平台上,但編譯為32位:
clang++ -m32 -std=c++11 type.cpp -o type-32-clang
給我以下結果:
std::ptrdiff_t is an alias for int
std::size_t is an alias for unsigned long
在這種情況下, std::size_t
不是std::ptrdiff_t
的無符號版本,即使它們具有相同的存儲大小(4個字節)。 雖然它符合標准,但對我來說似乎很奇怪。
有誰知道這個選擇的理由?
TL; DR:為了與其他系統兼容,為了與其他系統兼容,這樣做等等。
clang通常會像你預期的那樣為ptrdiff_t
和size_t
signed long
和unsigned long
,但是提交“在darwin / x86-32上修復apple gcc和clang之間的一些差異”將ptrdiff_t
更改為signed int
以與gcc兼容。 你不能讓clang和gcc使用相同的C ++庫,如果他們不同意這些基本的typedef。
gcc對size_t
使用unsigned long
,但為ptrdiff_t
使用signed int
,因為這是Apple貢獻的: commit“添加Darwin(Mac OS X內核)原生支持。” 在gcc/config/darwin.h
:
/* Target definitions for Darwin (Mac OS X) systems. Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001 Free Software Foundation, Inc. Contributed by Apple Computer Inc. [...] /* The string value for __SIZE_TYPE__. */ #ifndef SIZE_TYPE #define SIZE_TYPE "long unsigned int" #endif /* Type used for ptrdiff_t, as a string used in a declaration. */ #undef PTRDIFF_TYPE #define PTRDIFF_TYPE "int"
無特殊原因被提及,但這個文件不是針對任何處理器類型,它適用於所有Darwin系統,並提交也觸及gcc/config/rs6000/rs6000.h
,使得它有可能它是與兼容性,將它帶回1995年, 提交“添加初步V.4和eABI支持”。 :
/* Type used for ptrdiff_t, as a string used in a declaration. */ #undef PTRDIFF_TYPE #define PTRDIFF_TYPE "int"
由於這不會重新定義SIZE_TYPE
,因此保留默認值"unsigned long"
。
GCC不是系統的編譯器這個平台, 讓反過來很可能與IBM的編譯器的兼容性。 這似乎得到gcc/config/rs6000/aix43.h
:
/* AIX 4.3 typedefs ptrdiff_t as "long" while earlier releases used "int". */ #undef PTRDIFF_TYPE #define PTRDIFF_TYPE "long int"
由於AIX的歷史不公開,因此可能不會再發生這種情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.