2008-12-21 8 views
113

non molto tempo fa, qualcuno mi ha detto che non sono long 64 bit a 64 bit macchine e mi dovrebbe sempre usare int. Questo non aveva senso per me. Ho visto documenti (come quello sul sito ufficiale di Apple) affermare che long sono effettivamente 64 bit durante la compilazione per una CPU a 64 bit. Ho guardato quello che era a 64 bit di Windows e ha trovatoQual è la dimensione del bit di long su Windows a 64 bit?

  • di Windows: long e int rimangono a 32 bit di lunghezza, e speciali nuovi tipi di dati sono definiti per interi a 64 bit.

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

Cosa devo usare? Devo definire qualcosa come uw, sw (larghezza unilaterale) come long se non su Windows, e altrimenti fare un controllo sul bit della CPU di destinazione?

+0

Su Windows con MSVC++ int e long sono 32 bit: https://msdn.microsoft.com/en-us/library/3b2e7499.aspx. Tuttavia, per consentire ad es. i vettori per memorizzare più di 4G di articoli, size_t è 64 bit. Quindi è necessario utilizzare int64_t anziché int per eseguire iterate, ad es. vettori che possono contenere più di oggetti 4G. –

+0

In ** Cygwin ** ['sizeof (long) == 8', anche su Windows] (http://stackoverflow.com/a/39207744/485343) :-) – rustyx

+0

@SergeRogatch dovrebbero usare' size_t' o un tipo iteratore per iterare, non 'int' o' int64_t' –

risposta

0

Se avete bisogno di usare numeri interi di certa lunghezza, probabilmente dovrebbe utilizzare alcuni piattaforma intestazioni indipendenti per aiutarvi. Boost è un buon posto per guardare.

4

Questo articolo su MSDN fa riferimento a una serie di tipo alias (disponibile su Windows) che sono un po 'più esplicito rispetto alla loro larghezza:

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

Per esempio, anche se è possibile utilizzare ULONGLONG di riferimento un valore integrale senza segno a 64 bit, è inoltre possibile utilizzare UINT64. (Lo stesso vale per ULONG e UINT32.) Forse questi saranno un po 'più chiari?

+1

Esiste la garanzia che uint32_t e DWORD siano intercambiabili? Non è difficile immaginare che potrebbero non esserlo [ad es. se il primo è un 'int' a 32 bit e il secondo un' long' a 32 bit, gcc assume che un puntatore a un tipo non sia in grado di alias l'altro nonostante le corrispondenti rappresentazioni corrispondenti]. – supercat

2

Il modo più semplice per arrivare a conoscere per il vostro compilatore/piattaforma:

#include <iostream> 

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

Themultiplication da 8 bit è quello di ottenere dai byte.

Quando avete bisogno di una dimensione particolare, è spesso più facile da usare uno dei tipi predefiniti di una libreria. Se ciò non è desiderabile, puoi fare ciò che spesso accade con il software autoconf e fare in modo che il sistema di configurazione determini il tipo giusto per la dimensione necessaria.

+4

Non è importante, ma i byte a 8 bit non fanno parte delle specifiche C (clausola 3.6 e 5.2.4.2.1 dello standard C). Sebbene sia difficile trovare una macchina in cui non fossero 8 bit, è possibile selezionare LONG_BIT per vedere quanto è grande il proprio tipo di dati lungo. – Andres

+0

Ovviamente, hai ragione, in realtà dipende dall'architettura ("unità indirizzabile di archiviazione dei dati abbastanza grande da contenere qualsiasi membro del set di caratteri di base dell'ambiente di esecuzione"), ma le architetture più comunemente usate equivalgono a 8 bit. –

+0

Ma l'OP non ha chiesto il * suo * compilatore/piattaforma; ha chiesto specificamente su Windows a 64 bit, presumibilmente perché * non * ha un comodo accesso a un sistema Windows a 64 bit per testare. – Quuxplusone

3

Microsoft ha anche definito UINT_PTR e INT_PTR per gli interi che sono le stesse dimensioni di un puntatore.

Ecco un list of Microsoft specific types - è parte del loro riferimento conducente, ma credo che sia valida per la programmazione in generale.

222

Nel mondo Unix, ci sono stati alcuni accordi possibili per le dimensioni dei numeri interi e puntatori per le piattaforme a 64 bit. I due per lo più ampiamente usati erano ILP64 (in realtà, solo pochi esempi di questo, Cray era uno di questi) e LP64 (per quasi tutto il resto). Gli acronynms provengono da "int, long, i puntatori sono 64 bit" e "long, i puntatori sono 64 bit".

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 

Il sistema ILP64 è stata abbandonata a favore di LP64 (cioè, quasi tutti successivi entranti utilizzati LP64, sulla base delle raccomandazioni del gruppo Aspen, solo i sistemi con una lunga eredità di funzionamento a 64 bit utilizzare un diverso schema). Tutti i moderni sistemi Unix a 64 bit utilizzano LP64. MacOS X e Linux sono entrambi moderni sistemi a 64 bit.

Microsoft utilizza uno schema diverso per la transizione a 64 bit: LLP64 ('long long, pointers are 64-bit'). Ciò ha il merito di significare che il software a 32 bit può essere ricompilato senza modifiche. Ha il demerito di essere diverso da quello che fanno tutti gli altri, e richiede anche la revisione del codice per sfruttare le capacità a 64 bit. C'è sempre stata una revisione necessaria; era solo una diversa serie di revisioni rispetto a quelle necessarie sulle piattaforme Unix.

Se si progetta il software in circolazione nomi di tipo integer indipendente dalla piattaforma, probabilmente utilizzando l'intestazione C99 <inttypes.h>, che, quando i tipi sono disponibili sulla piattaforma, prevede, firmato (quotata) e unsigned (non quotate; prefisso con 'u'):

  • int8_t - interi a 8 bit
  • int16_t - interi a 16 bit
  • int32_t - interi a 32 bit
  • int64_t-64-bit tegers
  • uintptr_t - interi senza segno abbastanza grande per contenere i puntatori
  • intmax_t - il più grande formato di numero intero sulla piattaforma (potrebbero essere più grande di int64_t)

È quindi possibile codificare l'applicazione utilizzando questi tipi dove conta e facendo molta attenzione ai tipi di sistema (che potrebbero essere diversi). C'è un tipo intptr_t - un tipo intero con segno per contenere puntatori; si dovrebbe pianificare di non utilizzarlo o utilizzarlo solo come risultato di una sottrazione di due valori uintptr_t (ptrdiff_t).

Ma, come la domanda indica (increduli), ci sono diversi sistemi per le dimensioni dei tipi di dati interi su macchine a 64 bit. Abituati ad esso; il mondo non cambierà.

+8

Per quelli di uso che sono stati in giro abbastanza a lungo, la transizione a 64 bit ha alcuni paralleli con la transizione da 16 bit a 32 bit della metà degli anni '80. C'erano computer che erano IL32 e altri che erano L32 (adattando la nuova notazione al vecchio problema). A volte "int" era a 16 bit, a volte a 32 bit. –

+2

Non dimenticare che questo si applica solo alle lingue C-ish. Altri hanno specifiche più precise dove a) lo scrittore del compilatore non è autorizzato a scegliere la dimensione dei tipi di dati willi-nilly o b) la rappresentazione fisica dei tipi di dati non "perde" o c) gli interi sono sempre infinitamente grandi. –

+0

Vero - ma per quelle lingue che specificano il comportamento, non c'è un problema in primo luogo. Ad esempio, Java ha un 'long', ma la dimensione è fissa (64-bit?), Su tutte le piattaforme. Quindi, non ci sono problemi di porting su una macchina a 64 bit; la dimensione non cambia. –

38

Non è chiaro se la domanda riguarda il compilatore Microsoft C++ o l'API di Windows. Tuttavia, non esiste un tag [C++] quindi presumo che riguardi l'API di Windows. Alcune delle risposte hanno sofferto di link rot, quindi sto fornendo ancora un altro link che può marcire.


Per informazioni sui tipi di API di Windows come INT, LONG ecc C'è una pagina su MSDN:

Windows Data Types

Le informazioni sono disponibili in vari file di intestazione di Windows, come anche WinDef.h. Ho elencato alcuni tipi rilevanti qui:

 
Type      | S/U | x86 | x64 
----------------------------+-----+--------+------- 
BYTE, BOOLEAN    | U | 8 bit | 8 bit 
----------------------------+-----+--------+------- 
SHORT      | S | 16 bit | 16 bit 
USHORT, WORD    | U | 16 bit | 16 bit 
----------------------------+-----+--------+------- 
INT, LONG     | 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 

La colonna "S/U" indica firmato/unsigned.

+3

Tre anni e mezzo dopo, e il tuo link è ancora buono – makoshichi

Problemi correlati