64 bit Windows'ta bit boyutu ne kadardır?


137

Uzun zaman önce, birisi bana long64 bit makinelerde 64 bit olmadığını söyledi ve her zaman kullanmalıyım int. Bu benim için anlamlı değildi. Dokümanları gördüm (Apple'ın resmi sitesindeki gibi) long, 64 bit CPU için derlerken gerçekten 64 bit olduğunu söylüyor . 64 bit Windows'ta ne olduğunu araştırdım ve buldum

  • Pencereler: longve intuzunluk olarak 32-bit kalır ve özel yeni veri tipleri 64 bit tamsayılar için tanımlanmıştır.

( http://www.intel.com/cd/ids/developer/asmo-na/eng/197664.htm?page=2 adresinden )

Ne kullanmalıyım? Ben böyle bir şey tanımlamak gerekir uw, swbir şekilde ((me) imzalı genişlik) longdeğilse Windows üzerinde, aksi takdirde hedef CPU bitsize bir kontrol yapmak?


MSVC ++ int ve long içeren Windows'ta 32 bit vardır: msdn.microsoft.com/en-us/library/3b2e7499.aspx . Bununla birlikte, örneğin vektörlerin 4G'den fazla öğe depolamasına izin vermek için size_t 64 bittir. Bu nedenle yinelemek için int yerine int64_t kullanılmalıdır, örneğin 4G'den fazla öğe içerebilen vektörler.
Serge Rogatch


@SergeRogatch kullanmaları size_tya da yinelemek için bir yineleyici türü intya da değilint64_t
phuclv

2
@ LưuVĩnhPhúc, size_tnegatif sayılar yakınında zorlaşır, çünkü imzasızdır size_t. Yani for(size_t i=0; i<v.size()-2; i++)vektör büyüklüğü 0 ve 1 başka örneğin başarısız: for(size_t i=v.size()-1; i>=0; i--).
Serge Rogatch

2
Eğer işaretçiler üzerinde matematik yapıyorsanız (yani size_tdeğerlerle o zaman sonuç ptrdiff_ttür bir değişkente tutulmalıdır - böyle bir sonucu tutacak kadar büyük olacak şekilde tasarlanmıştır ve tam da bu nedenle imzalı bir tiptir!)
SlySven

Yanıtlar:


261

Unix dünyasında, 64 bit platformlar için tamsayıların ve işaretçilerin boyutları için birkaç olası düzenleme vardı. En yaygın olarak kullanılan ikisi ILP64 (aslında, bunun sadece birkaç örneği; Cray böyle biriydi) ve LP64 (hemen hemen her şey için) idi. Kısaltmalar 'int, long, işaretçiler 64-bit' ve 'long, işaretçiler 64-bit'tir.

Type           ILP64   LP64   LLP64
char              8      8       8
short            16     16      16
int              64     32      32
long             64     64      32
long long        64     64      64
pointer          64     64      64

ILP64 sistem lehine terk edildi LP64 (; 64 bit işletim uzun bir geçmişe sahip tek sistem farklı bir şekil kullandığını olduğunu, neredeyse tüm sonraki girenlerin Aspen grubunun önerilerine göre, LP64 kullanılır). Tüm modern 64 bit Unix sistemleri LP64 kullanır. MacOS X ve Linux'un her ikisi de modern 64 bit sistemlerdir.

Microsoft 64-bit'e geçiş için farklı bir şema kullanır: LLP64 ('uzun, işaretçiler 64-bit'). Bu, 32 bit yazılımın değişiklik yapılmadan yeniden derlenebileceği anlamına gelir. Herkesin yaptıklarından farklı olma ve 64 bit kapasitelerin kullanılması için kodun revize edilmesini gerektiriyor. Her zaman revizyon gerekliydi; Unix platformlarında ihtiyaç duyulanlardan sadece farklı bir düzeltme grubuydu.

Yazılımınızı platformdan bağımsız tamsayı türü isimleri etrafında tasarlarsanız, muhtemelen C99 <inttypes.h>üstbilgisini kullanırsınız ;

  • int8_t - 8 bit tamsayılar
  • int16_t - 16 bit tamsayılar
  • int32_t - 32 bit tamsayılar
  • int64_t - 64 bit tamsayılar
  • uintptr_t - işaretçileri tutacak kadar büyük işaretsiz tam sayılar
  • intmax_t- platformdaki en büyük tamsayı boyutu (daha büyük olabilir int64_t)

Daha sonra uygulamanızı önemli olan bu türleri kullanarak ve sistem türlerine (farklı olabilir) çok dikkat ederek kodlayabilirsiniz. Bir intptr_ttür vardır - işaretçileri tutmak için imzalı bir tamsayı türü; kullanmamayı veya yalnızca iki uintptr_tdeğerin çıkarılması sonucunda kullanmayı planlamalısınız ( ptrdiff_t).

Ancak, sorunun işaret ettiği gibi (güvensizlikle), 64 bitlik makinelerde tamsayı veri türlerinin boyutları için farklı sistemler vardır. Alışmak; dünya değişmeyecek.


12
Yeterince uzun süredir kullanımda olan kullanıcılar için, 64 bitlik geçişin 80'lerin ortasında 16 bitlik ila 32 bitlik geçişle bazı paralellikleri var. IL32 olan bilgisayarlar ve L32 olan diğerleri vardı (yeni gösterimi eski probleme uyarlayan). Bazen 'int' 16-bit, bazen 32-bit idi.
Jonathan Leffler

4
Bunun sadece C-ish dilleri için geçerli olduğunu unutmayın. Diğerleri, a) derleyici yazarının willi-nilly veri tiplerinin boyutunu seçmesine izin verilmediği veya b) veri tiplerinin fiziksel temsili "sızdırmaz" veya c) tamsayıların her zaman sonsuz büyüklükte olduğu daha spesifik özelliklere sahiptir.
Jörg W Mittag

2
Doğru - ancak davranışı belirten diller için, ilk etapta bir sorun yoktur. Örneğin, Java'nın 'uzun' değeri vardır, ancak boyut tüm platformlarda sabittir (64 bit?). Bu nedenle, 64 bit makineye ilişkin hiçbir sorun yoktur; boyut değişmez.
Jonathan Leffler

17
@TFFobear: ILP64 önemli bir sorun sunuyor - 32 bit türüne ne diyorsunuz? Veya 32 bit türünü shortçağırırsanız, 16 bit türüne ne denir? charUTF-16 vb. İçin 16 bit türünü çağırırsanız, 8 bit türüne ne denir? Böylece, LP64 kullanmak sizi 8-bit char, 16-bit short, 32-bit int, 64-bit ile bırakır , bu uygun olduğunda long128-bit'e long longkadar genişletilebilir . Bundan sonra, C'de isimlerinizden 256'dan daha fazla güce sahipsiniz (sanırım 256-bitiniz olabilir intmax_tve ancak o zaman tükenirsiniz). LP64'e liyakat var.
Jonathan Leffler

2
Belki bu sizin için açıktır, ancak C # 'ın diğer her şeyden farklı tamsayı boyutları kullandığını belirtmek gerekir. Kısa bir süre önce bir DLL ile arabirim açtım, çünkü C # 64 bit uzunluğunda ( msdn.microsoft.com/en-us/library/ms173105.aspx ).
Compholio

57

Sorunun Microsoft C ++ derleyicisi veya Windows API'sı ile ilgili olup olmadığı açık değildir. Ancak, hiçbir [c ++] etiketi, bu yüzden Windows API hakkında olduğunu varsayalım. Bazı cevaplar bağlantı çürümesi oldu bu yüzden çürümeye başka bir bağlantı sağlıyorum.


Gibi Windows API türleri hakkında bilgi için INT, LONGvb MSDN'de bir sayfa vardır:

Windows Veri Türleri

Bilgi, gibi çeşitli Windows başlık dosyalarında da mevcuttur WinDef.h. Burada birkaç alakalı tür listeledim:

Türü | S / U | x86 | x64
---------------------------- + ----- + -------- + ------ -
BYTE, BOOLEAN | U | 8 bit | 8 bit
---------------------------- + ----- + -------- + ------ -
KISA | S | 16 bit | 16 bit
USHORT, WORD | U | 16 bit | 16 bit
---------------------------- + ----- + -------- + ------ -
INT, UZUN | S | 32 bit | 32 bit
UINT, ULONG, DWORD | U | 32 bit | 32 bit
---------------------------- + ----- + -------- + ------ -
INT_PTR, LONG_PTR, LPARAM | S | 32 bit | 64 bit
UINT_PTR, ULONG_PTR, WPARAM | U | 32 bit | 64 bit
---------------------------- + ----- + -------- + ------ -
LONGLONG | S | 64 bit | 64 bit
ULONGLONG, QWORD | U | 64 bit | 64 bit

"S / U" sütunu imzalı / imzasızdır.


4

MSDN'deki bu makale, genişliklerine göre biraz daha açık olan birkaç tür diğer adı (Windows'ta kullanılabilir) referans almaktadır:

http://msdn.microsoft.com/en-us/library/aa505945.aspx

Örneğin, 64 bit işaretsiz bir integral değerine başvurmak için ULONGLONG'u kullanabilmenize rağmen, UINT64'ü de kullanabilirsiniz. (Aynısı ULONG ve UINT32 için de geçerlidir.) Belki de bunlar biraz daha net olacak?


1
Uint32_t ve DWORD'nin değiştirilebilir olacağına dair herhangi bir garanti var mı? Bunların olmayabileceğini hayal etmek zor değil (örneğin, birincisi 32-bit intve ikincisi 32-bit ise long, gcc, bir tür işaretçi, eşleşen temsillerine rağmen diğerini taklit edemeyeceğini varsayar).
supercat

4

Microsoft ayrıca bir işaretçi ile aynı boyuttaki tamsayılar için UINT_PTR ve INT_PTR tanımlamıştır.

İşte Microsoft'a özgü türlerin bir listesi - sürücü referanslarının bir parçası, ancak genel programlama için de geçerli olduğuna inanıyorum.


2

Derleyiciniz / platformunuz için tanımanın en kolay yolu:

#include <iostream>

int main() {
  std::cout << sizeof(long)*8 << std::endl;
}

8 ile tema, baytlardan bit almaktır.

Belirli bir boyuta ihtiyacınız olduğunda, önceden tanımlanmış bir kitaplık türünden birini kullanmak genellikle en kolay yoldur. Bu istenmeyen bir durumsa, autoconf yazılımı ile sık sık ne yapabilirse ve yapılandırma sisteminin gerekli boyut için doğru türü belirlemesini sağlayabilirsiniz.


4
Önemli değil, ama 8 bit bayt aslında C spesifikasyonunun bir parçası değildir (C standardının 3.6 ve 5.2.4.2.1 maddesi). 8 bit olmayan bir makine bulmak zor olsa da, uzun veri tipinizin ne kadar büyük olduğunu görmek için LONG_BIT'i kontrol edebilirsiniz.
Andres

Tabii ki haklısınız, aslında mimariye bağlı ("yürütme ortamının temel karakter kümesinin herhangi bir üyesini tutacak kadar büyük adreslenebilir veri depolama birimi"), ancak 8 bite eşit olan en yaygın kullanılan mimariler.
Paul de Vrieze

Ama OP hakkında sormadı onun derleyici / platformu; o özellikle 64 bit Windows hakkında sorular - o muhtemelen çünkü vermez üzerinde test etmek için 64-bit Windows sistemine uygun erişim hakkına sahiptir.
Quuxplusone


-2

Belirli bir uzunlukta tamsayılar kullanmanız gerekiyorsa, muhtemelen size yardımcı olmak için platformdan bağımsız bazı başlıklar kullanmalısınız. Boost bakmak için iyi bir yerdir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.