2011-09-30 34 views
14

MinGW-64'ü indirdim, böylece Windows 7 için 64-bit programları g ++ 4.7.0 (deneysel) kullanarak derleyebilirim. Ama aşağıdaki satırı:64-bit C++ 'da uzun boylu (uzun) C++

cout << sizeof(long) << " " << sizeof(void*) << endl ; 

baskılar 4 8 değil 8 8. g ++ 4.6.0 belgeleri diyor ki:

64-bit ortamı setleri 32 bite int ve 64 bit

uzun ve işaretçi
sizeof(long) 8 olmamasının sebebi

bilen var mı?

Eklenme: Benim karışıklığımın kaynağı, 64-bit Windows için g ++ 4.7.0'ın (henüz) GNU Derleyici Koleksiyonunun resmi bir kısmı olmamasıydı. Ve bu 32-bit long ile ilk 64-bit sürümü, bu yüzden belgelere sadece onun için geçerli değildir. Eğer relevant web page giderseniz Nitekim, IA-32/x86-64 için tam giriş bu oluşur:

... microsoft windows işletim sistemi üzerinde

+2

Şunun gibi görünüyor: Birisi sadece seri olarak herhangi bir yorum bırakmadan cevapların yarısını düşürdü ... – Mysticial

+0

@Mystical: Ve benim sorum da! – TonyK

+0

64 bitlik bir tam sayıya ihtiyacınız varsa int64_t/uint64_t kullanın veya kendiniz tanımlayın. Bu şekilde kodunuz taşınabilir olacak ve int/long/short boyutları için platform özelliklerine güvenmeyecektir. – David

cevap

15

Çünkü olması gerekmiyor. C++ standardı, yalnızca (bellek sunulduğunda) en az 32 bit genişlikte ve en az int kadar büyük olmasını gerektirir. o ana OS

+1

C++ standardından bahsetmiyorum, GNU Compiler Collection'ın kendi belgelerinden bahsediyorum. – TonyK

+4

Biliyorum. Cevabımdaki ilk cümleyi oku. Ve sonuncusu. Sadece bulduğunuz belgelere (varsayalım) x64 üzerinde çalışan Linux için ABI'yi tanımlar.Diğer CPU'lar (ARM, MIPS, Alpha, SPARC ya da başka bir şey) hakkında hiçbir şey söylemiyor ve farklı işletim sistemlerine bağlantı noktaları hakkında hiçbir şey söylemiyor. – jalf

11

bunu LLP64 var uzunluğunun boyu 32 bittir. Wikipedia`dan

Alıntı (aşağıdaki tabloya bakınız):

32-bit programlar, örneğin tam sayı genellikle aynı uzunluğa sahip olarak işaretçiler ve veri türleri; Bu 64 bit makinelerde mutlaka doğru değildir. C ve onun C++ ve Objective-C gibi torunları gibi programlama dillerindeki veri türlerinin karıştırılması, 32 bit uygulamalarda çalışabilir, ancak 64 bit uygulamalarda kullanılamaz. 64 bit makinelerde C ve C türetilmiş diller için birçok programlama ortamında, "int" değişkenleri hala 32 bit genişliğinde, ancak uzun tamsayılar ve işaretçiler 64 bit genişliğindedir. Bunlar bir LP64 veri modeline sahip olarak tanımlanmıştır. Diğer bir alternatif, üç veri türünün 64 bit genişliğinde ve "kısa" tam sayıların da 64 bit genişliğinde olduğu SILP64'lerin bile bulunduğu ILP64 veri modelidir. Bununla birlikte, çoğu durumda, gerekli olan modifikasyonlar nispeten küçük ve basittir ve birçok iyi yazılmış program, değişiklik yapılmadan yeni ortam için yeniden derlenebilmektedir. Başka bir alternatif, 32 bit kod ile uyumluluğu hem int hem de 32-bit olarak bırakarak sürdüren LLP64 modelidir. "LL", 32 bit ortamlar dahil olmak üzere, tüm platformlarda en az 64 bit olan "uzun uzun tamsayı" türünü belirtir.

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 
+1

Belki de tablonun ne anlama geldiği hakkında bir açıklama *. ;) – jalf

+1

Referans bağlantısı nasıl? –

+0

Burada farklı modeller açıklanmaktadır: http://en.wikipedia.org/wiki/64-bit –

0

Bu işletim sistemi belirli. Windows'un hala uzun eşit 32 bitlik boyutu

0

Çoğu Windows uygulamalarının hemfikir olduğunda derleyici çok daha yararlıdır

MSVC (ve Windows tarafından kullanılan ABI) genişliğinde 32 bit olmak long tanımlar ve MinGW çünkü iyi takım izler Tüm niyet ve amaçlar için int = long = 32 bit olması beklentisiyle yazılır. Tahminimce MinGW hala durumun böyle olduğundan emin değil ve sürpriz yok.

2

MinGW bir WIN32 uygulaması oluşturmak için tasarlanmıştır ve WIN32 üstbilgileri/kitaplıkları, 64 bit Windows'da bile 32 bit genişliğinde uzun (veya UZUN) türünü varsayar. Microsoft, mevcut Windows kaynak kodlarının çoğunun değiştirilmesine karar verdi. Örneğin, aşağıdaki yapı UZUN tür kullanır.

typedef struct tagBITMAPINFOHEADER { 
... 
    LONG biWidth; 
    LONG biHeight; 
... 
} BITMAPINFOHEADER 

;

+0

'LONG' sadece bir makrodur. Bu, int32_t'ye kolayca değiştirilebilir, bu yüzden geçerli bir sebep değildir. – rustyx

0

MinGW, Windows uygulamaları ve int ve long numaralı Microsoft platformunun aynı boyutta 32 bit oluşturduğu ABI specifies için tasarlanmıştır. MinGW, MSVC'den farklı olarak long tanımlanmışsa, long kullanan çoğu Windows uygulaması, MinGW kullanılarak derlendiğinde kesilir.

Bunu söyledikten sonra, Cygwin x86_64, Linux'ta olduğu gibi (source) Windows'daki LP64 kuralını uygular. long büyüklüğü 8 byte :)

Test durumda olduğu

Yani Windows uygulama oluşturmak için kullanabilirsiniz:

#include <stdio.h> 
#include <windows.h> 

int CALLBACK WinMain(HINSTANCE a, HINSTANCE b, LPSTR c, int d) 
{ 
    char buf[100]; 
    snprintf(buf, sizeof(buf), 
    "sizeof(int)=%d, sizeof(long)=%d, sizeof(long long)=%d\n", 
    sizeof(int), sizeof(long), sizeof(long long)); 
    MessageBox(NULL, buf, "Cygwin Test", MB_OK); 
    return 0; 
} 

Derleme ile: C:\cygwin64\bin\gcc.exe -mwindows -m64 cygwin-test.c -o cygwin-test

Çıktı:

Windows 64-bit LP64 using Cygwin