insidie tipiche per 32bit/64bit porting sono:
L'assunto implicito dal programmatore che sizeof (void *) == 4 * sizeof (char). Se stai facendo questa ipotesi e per es. allocare gli array in questo modo ("Ho bisogno di 20 puntatori per allocare 80 byte"), il codice si interrompe a 64 bit perché causerà sovraccarichi del buffer.
Il "kitten-killer", int x = (int) e qualcosa; (e il contrario, void * ptr = (void *) some_int). Di nuovo un'ipotesi di sizeof (int) == sizeof (void *). Ciò non causa overflow ma perde i dati: il più alto 32 bit del puntatore, ovvero.
Entrambi questi problemi sono di una classe chiamata aliasing di tipo (assumendo identità/intercambiabilità/equivalenza su un livello di rappresentazione binaria tra due tipi) e tali ipotesi sono comuni; come in UN * X, supponendo time_t, size_t, off_t being int, o su Windows, HANDLE, void * e long intercambiabile, ecc ...
Presupposti sulla struttura dei dati/utilizzo dello spazio di stack (Vedi 5. sotto come bene). Nel codice C/C++, le variabili locali sono allocate nello stack e lo spazio utilizzato è diverso tra la modalità a 32 bit e 64 bit a causa del punto in basso, e a causa delle diverse regole per il passaggio degli argomenti (32 bit x86 di solito in pila, 64 bit x86 in parte nei registri). Il codice che fa quasi scappare lo stack predefinito su 32 bit potrebbe causare arresti anomali dello stack over a 64 bit. Questo è relativamente facile da individuare come causa del crash, ma dipende dalla configurabilità dell'applicazione, probabilmente difficile da risolvere.
Differenze di tempo tra codice a 32 bit e 64 bit (a causa di diverse dimensioni di codice/impronte di cache, o caratteristiche/modelli di accesso di memoria diversi o convenzioni di chiamata diverse) potrebbero interrompere le "calibrazioni". Supponi, per (int i = 0; i < 1000000; ++ i) sleep (0); è probabile che avrà tempi diversi per 32 bit e 64 bit ...
Infine, l'ABI (Application Binary Interface). Di solito ci sono differenze maggiori tra gli ambienti a 64 bit e 32 bit rispetto alle dimensioni dei puntatori ... Attualmente esistono due "rami" principali di ambienti a 64 bit, IL32P64 (ciò che usa Win64 - int e long sono int32_t, solo uintptr_t/void * è uint64_t, parlando in termini di numeri interi da) e LP64 (cosa usa UN * X - int è int32_t, long è int64_t e uintptr_t/void * è uint64_t), ma ci sono anche le "suddivisioni" di diverse regole di allineamento - alcuni ambienti assumono long, float o double align alle rispettive dimensioni, mentre altri assumono che si allineano a multipli di quattro byte. In Linux a 32 bit, allineano tutti a quattro byte, mentre in Linux a 64 bit, gli allineamenti float a quattro, lunghi e doppi a multipli di otto byte. La conseguenza di queste regole è che in molti casi, bith sizeof (struct {...}) e l'offset dei membri struttura/classe sono diversi tra ambienti 32bit e 64bit anche se la dichiarazione del tipo di dati è completamente identica. Oltre all'impatto sull'assegnazione di array/vettori, questi problemi influenzano anche i dati in/output, ad es. attraverso i file - se un'app a 32 bit scrive ad es. struct {char a; int b; char c, long d; double e} in un file che la stessa app ha ricompilato per la lettura a 64 bit, il risultato non sarà esattamente quello che si spera. Gli esempi appena forniti riguardano solo le primitive della lingua (char, int, long ecc.), Ma naturalmente influiscono su tutti i tipi di tipi di dati della libreria/runtime della piattaforma, se size_t, off_t, time_t, HANDLE, essenzialmente qualsiasi struttura/unione non banale/class ... - quindi lo spazio per l'errore qui è grande,
E poi ci sono le differenze di livello inferiore, che entrano in gioco ad esempio per il montaggio ottimizzato a mano (SSE/SSE2/...); 32 bit e 64 bit hanno registri diversi (numeri di), diverse regole di passaggio degli argomenti; tutto ciò influisce molto sul rendimento di tali ottimizzazioni ed è molto probabile che ad es. Il codice SSE2 che offre le migliori prestazioni in modalità 32 bit dovrà essere riscritto/deve essere migliorato per offrire la migliore modalità a 64 bit delle prestazioni.
Ci sono anche vincoli di progettazione del codice che sono molto diversi per 32 bit e 64 bit, in particolare per quanto riguarda l'allocazione/gestione della memoria; un'applicazione che è stata accuratamente codificata per "massimizzare l'inferno del mem che può ottenere in 32 bit" avrà una logica complessa su come/quando allocare/memoria libera, uso di file mappati in memoria, cache interna, ecc. essere dannoso in 64 bit in cui si potrebbe "semplicemente" sfruttare l'enorme spazio di indirizzamento disponibile. Una tale app potrebbe ricompilare per 64 bit semplicemente, ma si comporta peggio di qualche "antica versione deprecata semplice" che non ha tutte le ottimizzazioni degli spioncino massimizzabili a 32 bit.
Quindi, in definitiva, si tratta anche di miglioramenti e/o guadagni, ed è lì che più lavoro, in parte in programmazione, in parte in progettazione/requisiti viene in. Anche se la vostra applicazione ricompila modo pulito sia in ambienti 32bit e 64bit e viene verificata su entrambi , sta effettivamente beneficiando di 64 bit? Ci sono cambiamenti che possono/devono essere fatti alla logica del codice per farlo fare di più/correre più velocemente a 64 bit? Puoi fare queste modifiche senza rompere la compatibilità a 32 bit con le versioni precedenti? Senza impatti negativi sull'obiettivo a 32 bit? Dove saranno i miglioramenti e quanto puoi guadagnare? per un grande progetto commerciale, le risposte a queste domande sono spesso indicatori importanti sulla tabella di marcia, perché il punto di partenza è un po 'esistente "macchina da soldi" ...
awsome anwser :) proprio quello che stavo cercando :) –
@FredrikBostonWestman, allora dovresti accettarlo! – gsamaras