2012-05-17 19 views
5

Voglio poter utilizzare interi positivi grandi (8 byte) nel mio progetto, anche se sizeof (unsigned long) produce 8 nel mio sistema, ho letto che in la maggior parte dei sistemi non firmati è lunga solo 4 byte e ho deciso di fornire unsigned long long go, poiché è garantito che siano almeno 8 byte.non firmato lungo lungo vs non firmato lungo (punto di vista della portabilità)

Più lo uso però, ho visto che non è anche super portatile, ad esempio in alcuni sistemi (a seconda del compilatore) printf lo formatta con% llu, in alcuni lo formatta con% lld.

Il mio codice verrà eseguito solo in macchine debian a 64 bit, in cui unsigned long sarà 8 byte. La portabilità non è un grosso problema. E 'un eccessivo uso di unsigned long long unsigned long in queste circostanze, ci sono altri vantaggi nell'usare unsigned long long unsigned long?

+7

Hai provato "uint64_t'? È in ' .' – Mysticial

+0

qual è il vantaggio di usarlo su unsigned long long? –

+1

Arresta la compilazione se non si dispone di alcun tipo con esattamente 64 bit mentre lungo lungo lungo il tipo più lungo. Entrambi sono presenti in C++ 11, entrambi sono spesso presenti come estensione prima, ma non sarei sorpreso se qualcuno fosse presente e non l'altro.Se non ce l'hai, stdint.h è più facile da emulare (supponendo che il tipo sia presente) piuttosto che lungo. – AProgrammer

risposta

9

unsigned long long è garantito per essere almeno 64 bit, indipendentemente dalla piattaforma. (Ci sono piattaforme dove è più — Conosco 72 bit e 96 bit — ma sono rari e decisamente esotici.) unsigned long è garantito per essere almeno di 32 bit. Se hai bisogno di più di 32 bit, ti consiglio di specificare unsigned long long.

Per quanto riguarda la formattazione, con printf, è necessario utilizzare "%llu" (poiché non è firmato); "%lld" è per signed long long.

+0

grazie James, è quello che ho pensato anche io, è sicuramente più sicuro usare unsigned long long. Ecco la domanda però, dal momento che nel mio ambiente di sviluppo e di destinazione non firmato è di 8 byte, posso invece allontanarmi usando unsigned long invece? Tra l'altro il compilatore lancia un avvertimento quando uso% llu con un long lungo non firmato, questo tipo di non-portabilità mi spaventa dall'usare unsigned long long. –

+0

La garanzia "almeno 64 bit" è disponibile solo da C++ 11? – juanchopanza

+0

@erinc Se stai lavorando su una piattaforma in cui sia 'long long' che' long' hanno la stessa dimensione, il codice generato dovrebbe essere identico per loro, quindi non c'è motivo per non usare 'long long'. E se il compilatore avverte quando passa un 'long unsigned 'a un' "% llu" ', questo può essere considerato un bug. L'unico tipo legale da passare a ""% llu "' è 'unsigned long long'; passare qualsiasi altro tipo è un comportamento indefinito. –

0

Se è necessario assicurarsi di avere una dimensione fissa del valore intero, indipendente dalla piattaforma, è possibile utilizzare la libreria boost :: interi (vedere here). È possibile utilizzare boost :: int64_t o boost :: uint64_t per i valori senza segno

+0

perché usare boost e non lo stdint.h uint64_t? – WeaselFox

0

È possibile farlo se si vuole rimanere con lunghi e lunga lunga:

#include <limits.h> 
#if ULONG_MAX >= 0xFFFFFFFFFFFFFFFFULL 
typedef unsigned long uint64; 
#else 
typedef unsigned long long uint64; 
#endif 

W.r.t. questo

in alcuni sistemi (a seconda del compilatore) Formati printf IT con% llu, in qualche formatta con% LLD

printf() non indovinare il formato. Digli il formato.

Se si desidera un printf uint64 definito come in precedenza, fare in questo modo:

printf("%llu", (unsigned long long)some_uint64_value);

È possibile typedef unsigned long long ulonglong; per rendere il cast più facile da digitare.

Esistono altri modi per fare lo stesso, ma non tutti i compilatori li supportano. Questo è il motivo per cui ho allegato il suffisso ULL al numero. In alcune modalità di compatibilità tra C89 e C99, 0xFFFFFFFFFFFFFFFFFF può essere interpretato come unsigned long, non unsigned long long e verrà troncato. L'ultima versione di gcc per impostazione predefinita viene eseguita nella modalità gnu89 per il codice C, non c99 o successiva.