C standardı size_t
, herhangi bir dizi dizinini tutabilen bir tür olduğunu garanti eder . Bu, mantıksal olarak size_t
herhangi bir işaretçi türünü tutabilmesi gerektiği anlamına gelir . Google'da bulduğum bazı sitelerde bunun yasal olduğunu ve / veya her zaman çalışması gerektiğini okudum:
void *v = malloc(10);
size_t s = (size_t) v;
Böylece C99'da, standart , işaretçileri tutabilen garanti edilen imzalı ve imzasız tipler intptr_t
ve uintptr_t
türlerini tanıttı :
uintptr_t p = (size_t) v;
Peki size_t
ve ile arasındaki fark uintptr_t
nedir? Her ikisi de imzasızdır ve her ikisi de herhangi bir işaretçi türünü tutabilmelidir, bu nedenle işlevsel olarak aynı görünürler. Netlik dışında a yerine kullanmak için gerçek bir zorlayıcı neden var mı uintptr_t
(ya da daha iyisi, a void *
) size_t
? Alanın sadece dahili işlevlerle ele alınacağı opak bir yapıda, bunu yapmamak için herhangi bir neden var mı?
Aynı şekilde, ptrdiff_t
işaretçi farklılıklarını tutabilen ve bu nedenle herhangi bir işaretçiyi en fazla tutabilen imzalı bir tür olmuştur, peki nasıl farklıdır intptr_t
?
Bu türlerin tümü temelde aynı işlevin önemsiz derecede farklı sürümlerini sunmuyor mu? Değilse, neden? Biriyle diğerini yapamayacağım ne yapamam? Öyleyse, C99 neden dile temel olarak iki gereksiz tür ekledi?
Onlar mevcut sorun için geçerli değil, ama onlar "doğru" cevap merkezi olacak gizlice bir şüphe var gibi, onları belirtmekten çekinmeyin, işlev işaretçileri göz ardı etmeye hazırım.
size_t
veuintptr_t
ama ne hakkındaptrdiff_t
veintptr_t
- Bunlardan ikisi hemen hemen her platformda aynı aralıktaki değerler depolamak mümkün olmaz? Özellikleptrdiff_t
imzalı işaretçi boyutunda bir tamsayı türünün amacına hizmet ediyorsa, neden hem işaretli hem de işaretsiz işaretçi boyutu tamsayı türlerine sahip olmalısınız.