Niedawno ktoś mi powiedział, że long
na maszynach 64-bitowych nie ma 64 bitów i powinienem zawsze używać int
. To nie miało dla mnie sensu. Widziałem dokumenty (takie jak ta na oficjalnej stronie Apple), które mówią, że long
podczas kompilacji dla 64-bitowego procesora mają rzeczywiście 64 bity. Sprawdziłem, co to jest w 64-bitowym systemie Windows i znalazłem
- Windows:
long
iint
pozostają 32-bitowe, a specjalne nowe typy danych są definiowane dla 64-bitowych liczb całkowitych.
(z http://www.intel.com/cd/ids/developer/asmo-na/eng/197664.htm?page=2 )
Czego powinienem użyć? Należy zdefiniować coś podobnego uw
, sw
((un) podpisali szerokość) jako long
jeśli nie na Windows, a inaczej zrobić czek na bitsize cel procesora?
sizeof(long) == 8
, nawet na Windowsie :-)size_t
lub typu iteratora do iteracji, nieint
lubint64_t
size_t
który staje się trudny w pobliżu liczb ujemnych, ponieważsize_t
jest bez znaku. Więcfor(size_t i=0; i<v.size()-2; i++)
nie do wielkości wektora 0 i 1. Inny przykład:for(size_t i=v.size()-1; i>=0; i--)
.size_t
wartości to wynik powinien być przechowywany w zmiennejptrdiff_t
typu - który został zaprojektowany, aby być wystarczająco duże, aby utrzymać taki wynik i jest podpisany typ dla właśnie ten powód!)Odpowiedzi:
W świecie uniksowym istniało kilka możliwych konfiguracji rozmiarów liczb całkowitych i wskaźników dla platform 64-bitowych. Dwa najczęściej używane to ILP64 (właściwie tylko kilka przykładów; Cray był jednym z nich) i LP64 (do prawie wszystkiego innego). Akronynmy pochodzą od „int, long, wskaźniki są 64-bitowe” i „long, wskaźniki są 64-bitowe”.
Zrezygnowano z systemu ILP64 na rzecz LP64 (czyli prawie wszyscy późniejsi uczestnicy korzystali z LP64, w oparciu o zalecenia grupy Aspen; tylko systemy z długą tradycją 64-bitowego działania używają innego schematu). Wszystkie nowoczesne 64-bitowe systemy Unix używają LP64. MacOS X i Linux to nowoczesne systemy 64-bitowe.
Firma Microsoft używa innego schematu przejścia na wersję 64-bitową: LLP64 („długie długie, wskaźniki są 64-bitowe”). Ma to tę zaletę, że oznacza, że oprogramowanie 32-bitowe można ponownie skompilować bez zmian. Ma wadę polegającą na tym, że różni się od tego, co robią wszyscy inni, a także wymaga korekty kodu, aby wykorzystać pojemność 64-bitową. Zawsze była konieczna korekta; był to po prostu inny zestaw poprawek niż te potrzebne na platformach Unix.
Jeśli projektujesz oprogramowanie w oparciu o nazwy typów całkowitych neutralnych dla platformy, prawdopodobnie przy użyciu
<inttypes.h>
nagłówka C99 , który, gdy typy są dostępne na platformie, zawiera podpisane (wymienione) i niepodpisane (niewymienione; przedrostek z literą „u”):int8_t
- 8-bitowe liczby całkowiteint16_t
- 16-bitowe liczby całkowiteint32_t
- 32-bitowe liczby całkowiteint64_t
- 64-bitowe liczby całkowiteuintptr_t
- liczby całkowite bez znaku wystarczająco duże, aby pomieścić wskaźnikiintmax_t
- największy rozmiar liczby całkowitej na platformie (może być większy niżint64_t
)Następnie możesz zakodować swoją aplikację przy użyciu tych typów, jeśli ma to znaczenie, i bardzo ostrożnie z typami systemów (które mogą być różne). Istnieje
intptr_t
typ - typ liczby całkowitej ze znakiem do przechowywania wskaźników; powinieneś planować nie używać go lub używać go tylko w wyniku odejmowania dwóchuintptr_t
wartości (ptrdiff_t
).Ale, jak wskazuje pytanie (z niedowierzaniem), istnieją różne systemy rozmiarów całkowitych typów danych na maszynach 64-bitowych. Przyzwyczaić się do tego; świat się nie zmieni.
źródło
short
, jak nazwiesz typ 16-bitowy? A jeśli nazwiesz typ 16-bitowychar
dla UTF-16 itp., Jak nazwiesz typ 8-bitowy? Tak więc, użycie LP64 daje ci 8-bitowychar
, 16-bitowyshort
, 32-bitowyint
, 64-bitowylong
, z miejscem na rozszerzenie do 128-bitowego,long long
kiedy (jeśli?) Stanie się to istotne. Potem masz więcej potęg 256 niż nazwy w C (cóż, przypuszczam, że możesz mieć 256-bitoweintmax_t
i dopiero wtedy się wyczerpią). LP64 ma swoje zalety.Nie jest jasne, czy pytanie dotyczy kompilatora Microsoft C ++, czy interfejsu API systemu Windows. Jednak nie ma tagu [c ++], więc zakładam, że dotyczy interfejsu API systemu Windows. Niektóre odpowiedzi cierpią z powodu gnicia linków, więc podaję kolejny link, który może się zgnić.
Aby uzyskać więcej informacji na temat typów, takich jak Windows API
INT
,LONG
itd. Istnieje strona na MSDN:Typy danych systemu Windows
Informacje są również dostępne w różnych plikach nagłówkowych Windows, takich jak
WinDef.h
. Wymieniłem tutaj kilka odpowiednich typów:Kolumna „S / U” oznacza ze znakiem / bez znaku.
źródło
Ten artykuł na temat MSDN odwołuje się do szeregu aliasów typów (dostępnych w systemie Windows), które są nieco bardziej wyraźne pod względem ich szerokości:
http://msdn.microsoft.com/en-us/library/aa505945.aspx
Na przykład, chociaż możesz użyć ULONGLONG do odniesienia do 64-bitowej wartości całkowitej bez znaku, możesz również użyć UINT64. (To samo dotyczy ULONG i UINT32.) Być może te będą nieco jaśniejsze?
źródło
int
a drugi 32-bitowylong
, gcc założyłby, że wskaźnik do jednego typu nie byłby w stanie aliasować drugiego pomimo ich pasujących reprezentacji].Firma Microsoft zdefiniowała również UINT_PTR i INT_PTR dla liczb całkowitych, które mają taki sam rozmiar jak wskaźnik.
Oto lista specyficznych typów firmy Microsoft - jest to część odniesienia do sterowników, ale uważam, że jest to również ważne dla ogólnego programowania.
źródło
Najłatwiejszy sposób na poznanie tego dla twojego kompilatora / platformy:
Mnożenie przez 8 ma na celu uzyskanie bitów z bajtów.
Gdy potrzebujesz określonego rozmiaru, często najłatwiej jest użyć jednego z predefiniowanych typów biblioteki. Jeśli jest to niepożądane, możesz zrobić to, co często dzieje się z oprogramowaniem autoconf i poprosić system konfiguracji o określenie odpowiedniego typu dla wymaganego rozmiaru.
źródło
Rozmiar w bitach
long
na platformach Windows wynosi 32 bity (4 bajty).Możesz to sprawdzić za pomocą
sizeof(long)
.źródło
Jeśli potrzebujesz użyć liczb całkowitych o określonej długości, prawdopodobnie powinieneś użyć nagłówków niezależnych od platformy. Boost to dobre miejsce do obejrzenia.
źródło