簡體   English   中英

std :: ptrdiff_t和std :: size_t的奇怪typedef

[英]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_tsize_t signed longunsigned 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM