Domanda

Attualmente sto lavorando sulla conversione di un 32bit applicazione in un 64bits applicazione in C.Questa applicazione è attualmente al lavoro su architettura x86 (Windows, osx, Unix, Linux).Quindi, prima di iniziare la codifica, volevo sapere cosa devo prendere in considerazione, mentre la conversione di applicazione.

È stato utile?

Soluzione

  1. Scopri chi l'ha scritto. Sono un idiota? Sono tu di qualche anno fa? Puoi porre loro domande? Conoscono l'esistenza di più piattaforme e sistemi? Conoscere la mentalità degli autori del programma ti aiuterà a capire i problemi quando li incontri.
  2. Avvia e avvia un ambiente macchina / build a 64 bit.
  3. Sostituisci long con int. Sii perfettamente consapevole che LONG non è long.
  4. Sostituisci (int)&x cast e digita con intptr_t e (unsigned int)&x con uintptr_t
  5. Controlla tutto ciò che si basa sul cast di strutture su char* per eseguire l'aritmetica del puntatore con esso.
  6. Ricerca Regex per \ < 4 \ > nel caso tu abbia assunto 4 = sizeof(void*)
  7. Sii paziente. Quando trovi un problema, cerca altrove se esiste lo stesso problema e avvolgi la soluzione in una macro.
  8. Cerca di non utilizzare #ifdef RUN64 o qualcosa di simile. Te ne pentirai se le piattaforme a 128 bit andranno mai in voga.
  9. Incapsula tutte le tue modifiche in termini di alcune macro centralizzate che nasconderanno le differenze di portabilità altrove nel tuo programma.
  10. Utilizza un tester di copertura per assicurarti di aver coperto tutto (se appropriato)

EDIT ha aggiunto <=> nota come suggerito dal commento.

Altri suggerimenti

Un potenziale problema non già menzionato è che se la tua app legge o scrive dati binari dal disco (ad esempio, leggi una matrice di strutture usando fread), dovrai controllare molto attentamente e forse finire per avere due lettori: uno per i file legacy e uno per i file a 64 bit. Oppure, se stai attento a usare tipi come uint32_t e così via dal file di intestazione <stdint.h>, puoi ridefinire le tue strutture in modo che siano compatibili bit-per-bit. In ogni caso, I / O binario è una cosa a cui prestare attenzione.

Dipende molto dall'applicazione e da come è stata codificata. Alcuni codici possono essere semplicemente ricompilati con un compilatore a 64 bit e funzioneranno, ma di solito ciò accade solo se il codice è stato progettato pensando alla portabilità.

Se il codice ha molte ipotesi sulla dimensione dei tipi e dei puntatori nativi, se ha molti hack di bit packing o parla con un processo esterno usando un protocollo specificato da byte ma usando alcune ipotesi sulla dimensione di tipi nativi quindi potrebbe richiedere un po 'di lavoro per ottenere una compilazione pulita.

Praticamente ogni avviso di cast e compilatore è una bandiera rossa che deve essere verificata. Se il codice non era & Quot; avviso pulito & Quot; per cominciare, questo è anche un segno che potrebbe essere necessario molto lavoro.

Se hai usato i tipi corretti per i tuoi valori, ad es. size_t, ptrdiff_t, uintptr_t, i tipi int di dimensioni fisse da stdint.h ove appropriato - e non hanno hardcodificato le dimensioni del valore, il codice dovrebbe funzionare immediatamente.

Il problema principale che si presenta quando si passa a 64 bit è che la dimensione dei puntatori è diversa (64 bit anziché 32 - duh) Anche la dimensione degli interi e la dimensione dei long potrebbero differire, a seconda della piattaforma.

Perché questo è un problema? Beh, non lo è, a meno che il tuo codice non presupponga che sizeof (int) == sizeof (void *). Questo potrebbe portare a cattivi bug puntatore.

Beh, fondamentalmente, il numero di modifiche sono abbastanza piccole, ma sarà comunque un compito importante se l'applicazione non è scritto con attenzione per essere un po ' il portatile per iniziare con.

La differenza principale è che i puntatori sono a 64 bit, ma la maggior parte degli altri tipi di dati sono invariati.Int è ancora a 32 bit, e un lungo, probabilmente, è anche ancora a 32 bit.Quindi, se il vostro codice getta tra int e puntatori, che sta per rompersi.Allo stesso modo, qualsiasi struttura o simili che dipende da una specifica offset di un membro può rompersi a causa di altri membri possono ora essere più grande, e quindi modificare l'offset.

Naturalmente, il codice dovrebbe mai fare affidamento su questi trucchi in primo luogo, così, in un mondo ideale, questo non sarebbe un problema, e si potrebbe semplicemente ricompilare e tutto dovrebbe funzionare.Ma probabilmente non vivete in un mondo ideale...;)

Le due principali differenze tra la programmazione a 32 e 64 bit in C sono sizeof (void *) e sizeof (long). Il problema principale che avrai è che la maggior parte dei sistemi Unix utilizza lo standard I32LP64 che definisce fino a 64 bit e Win64 utilizza lo standard IL32LLP64 che definisce fino a 32 bit. Se è necessario supportare la compilazione multipiattaforma, è possibile utilizzare un set di typedef basati su architettura per numeri interi a 32 e 64 bit per garantire che tutto il codice si comporti in modo coerente. Questo viene fornito come parte di stdint.h come parte dello standard C99. Se non si utilizza un compilatore C99, potrebbe essere necessario eseguire il roll del proprio equivalente

Come notato altrove, le preoccupazioni principali per la conversione saranno il codice che assume sizeof (int) == sizeof (long) == sizeof (void *), il codice per supportare i dati scritti su disco e il codice per IPC multipiattaforma .

Per una buona recensione della storia dietro questo, dai un'occhiata a questo articolo dalla coda ACM.

Ci sono già molte buone risposte.

Valuta l'utilizzo di Gimpel Lint . Può indicare esattamente i tipi di costrutti che sono problematici. Se la tua esperienza è come la mia, ti mostrerà anche molti bug nel sistema non correlati alla porta a 32/64 bit.

Tutto su 64-bit per gli sviluppatori:

Articoli su Sviluppo a 64 bit

Raccolta di collegamenti Risorse a 64 bit

Strumento Viva64

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top