Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

int long e pointer, attenti ai 64 bit!

12 views
Skip to first unread message

Gianpaolo Ingegneri

unread,
Feb 16, 2012, 11:37:44 AM2/16/12
to
A me è capitato di vedere diversi listati che usano il long con la
convinzione che sia sempre a 32 bit su tutti i sistemi, mentre in realtà non
è così. La convizione che soltanto int possa variare il numero dei bit è
errata, per cui ho pensato di scrivere questo messaggio per aiutare qualche
programmatore a non commettere più questo errore. Quando si passa da un
windows a 32 bit ad un linux a 64 bit o un macosx bisogna fare molta
attenzione. I sistemi che variano il numero di bit negli int, long e
pointer, sono classificati in 3 categorie:

ILP64: Int, Long, Pointer a 64 bit
LP64: Long, Pointer a 64 bit
LLP64: Long Long, Pointer a 64 bit

In tutte e tre le categorie char e short sono sempre a 8 e 16 bit, mentre
long long è sempre a 64 bit. Quelli incerti sono solo int, long e pointer.
Per evitare di avere problemi col passaggio da una piattaforma all'altra, è
possibile usare dei tipi di interi definiti nella <inttypes.h> a numero
fisso di bits, rispettivamente:

int8_t - 8-bit integer
int16_t - 16-bit integer
int32_t - 32-bit integer
int64_t - 64-bit integer
uintptr_t - unsigned integer grande abbastanza da contenere un puntatore
intmax_t - l'intero con il size più grande sulla piattaforma utilizzata

Per mantere una buona compatibilità, consiglio di programmare sempre in modo
esatto il numero di bits utilizzati dalle variabili dei vostri algoritmi.
L'errore nel gestire correttamente questi tipi si può riscontrare nelle
lezioni di opengl del nehe.


Davide Pasca

unread,
Feb 20, 2012, 5:42:30 AM2/20/12
to
On 2012/02/17 1:37, Gianpaolo Ingegneri wrote:
> A me è capitato di vedere diversi listati che usano il long con la
> convinzione che sia sempre a 32 bit su tutti i sistemi, mentre in realtà non
> è così. La convizione che soltanto int possa variare il numero dei bit è
> errata, per cui ho pensato di scrivere questo messaggio per aiutare qualche

Io per indici ormai uso quasi esclusivamente size_t.
La "int" la considero almeno 32 bit. Il che non e' necessariamente vero,
ma all'atto pratico non penso di dover mettere mano su una architettura
< 32 bit per il futuro 8)
La "long" l'ho debellata da anni, anche se su Amiga e MS-DOS mi ci ero
affezionato.

Per dove mi serve una precisione specifica, ho i tipi In, Un dove "n" e'
8, 16, 32, 64.

mumble
Davide

--- Posted via news://freenews.netfront.net/ - Complaints to ne...@netfront.net ---

Gianpaolo Ingegneri

unread,
Feb 20, 2012, 8:04:33 AM2/20/12
to
> Io per indici ormai uso quasi esclusivamente size_t.
> La "int" la considero almeno 32 bit. Il che non e' necessariamente vero,
> ma all'atto pratico non penso di dover mettere mano su una architettura <
> 32 bit per il futuro 8)

Il problema viene quando carichi da file un int presupposto a 32 bit, tipo:

int width;
fread(&width, 4, 1, file);

Se int è a 64 bit si rischia di avere un valore errato di width perchè si
scriverebbe nei suoi primi 4 bytes. In effetti si potrebbe shiftare width in
base alla sua dimensione però non è tanto efficente, è preferibile avere dei
tipi a dimensione fissa soprattutto quando si salva e si carica da file.

Un discorso a parte meriterebbe l'Endianness, la funzione fread assieme ad
altre sono endianness dependant anche se fanno parte dello standard! Per cui
chi pensa di usare SDL e fare del codice crossplatform limitandosi allo
standard ANSI, deve stare molto attento a queste insidie. Per lavorare con
formati proprietari sarebbe opportuno prendere un endianness di riferimento
(es: little endian) e fare un overload delle funzioni di sistema. Ad
esempio:

double friction;
fread_little(&friction, 8, 1, file);

Si occuperebbe di caricare il parametro friction correttamente su sistemi
little endian o big endian avendo un little endian come punto di
riferimento. L'endianess di riferimento può essere salvata all'interno del
formato proprietario. C'è da dire inoltre che il byte order di riferimento
per il network è il big-endian, per cui bisogna fare attenzione anche a
questo.


Davide Pasca

unread,
Feb 20, 2012, 7:55:59 PM2/20/12
to
On 2012/02/20 22:04, Gianpaolo Ingegneri wrote:
>> Io per indici ormai uso quasi esclusivamente size_t.
>> La "int" la considero almeno 32 bit. Il che non e' necessariamente vero,
>> ma all'atto pratico non penso di dover mettere mano su una architettura<
>> 32 bit per il futuro 8)
>
> Il problema viene quando carichi da file un int presupposto a 32 bit, tipo:
>
> int width;
> fread(&width, 4, 1, file);

Certo.. infatti e' proprio in quei casi che uso i tipi con un numero ben
definito di bits.
Diciamo che generalmente distinguo tra storage ed uso.
Nel caso di storage e' essenziale avere un numero preciso. Nel caso di
uso basta sapere che ci sono abbastanza bits, quindi basta un limite minimo.

> Un discorso a parte meriterebbe l'Endianness, la funzione fread assieme ad
> altre sono endianness dependant anche se fanno parte dello standard! Per cui

Io ultimamente sto ignorando l'endianness per quanto riguarda i miei
formati binari, perche' in pratica ormai e' tutto little endian.
Anche se la mia preferenza personale era per big endian.. ma non e' una
cosa che si puo' scegliere 8)

Caruso Pascoshi

unread,
Feb 20, 2012, 8:08:09 PM2/20/12
to
On Feb 20, 2:04 pm, "Gianpaolo Ingegneri"
Se ti interessa puoi guardare nel codice di POSH http://www.hookatooka.com/wpc/
come Hook risolveva i basic type, l'endianess e altro.

Gianpaolo Ingegneri

unread,
Feb 21, 2012, 8:42:29 AM2/21/12
to

>Se ti interessa puoi guardare nel codice di POSH
>http://www.hookatooka.com/wpc/
> come Hook risolveva i basic type, l'endianess e altro.

Grazie :-)


0 new messages