printf con sizeof su piattaforme 32 vs 64: come gestisco il codice di formato in modo indipendente dalla piattaforma?

StackOverflow https://stackoverflow.com/questions/1403074

  •  05-07-2019
  •  | 
  •  

Domanda

Ho del codice che stampa la quantità di memoria utilizzata dal programma. La linea è simile a questa:

printf("The about of RAM used is %u", anIntVariable*sizeof(double) );

dove anIntVariable è una variabile int per il numero di elementi del doppio array. Ad ogni modo, sui sistemi a 32 bit non ho mai avuto problemi ma sui sistemi a 64 bit, ricevo un avviso del compilatore sull'uso di "% u " per un intero lungo senza segno. Utilizzando "% lu " poiché il codice di formato risolve il problema a 64 bit, ma causa la lamentela del compilatore a 32 bit perché il tipo è tornato a int senza segno. Ho scoperto che, in effetti, sizeof (double) restituisce un valore diverso su sistemi 32 vs 64 bit. Ho trovato alcune guide di pagine Web per convertire il codice da 32 bit a 64 bit Ma preferirei avere un codice che funzioni su entrambi invece di convertire semplicemente avanti e indietro.

Come scrivo questa riga in modo indipendente dalla piattaforma? Conosco molti modi per farlo usando le direttive del preprocessore, ma sembra un trucco. Sicuramente c'è un modo elegante che non sto realizzando.

È stato utile?

Soluzione

Gli identificatori portatili printf sono forniti nel file include inttypes.h .

Questo file include ha molti identificatori portatili per il tuo runtime specifico. Per il tuo esempio, vuoi PRIuPTR, che significa " PR intf I dentificatore u firmato con dimensioni fino a dimensioni di un puntatore ".

Il tuo esempio sarà quindi:

printf("The amount of RAM used is %" PRIuPTR, anIntVariable*sizeof(double) );

Risultati su Linux a 64 bit con GCC 4.3 ( int anIntVariable = 1 ):

$ gcc test.c -m32 -o test && ./test
The amount of RAM used is 8
$ gcc test.c -o test && ./test
The amount of RAM used is 8

Per completezza, ci sono identificatori anche per scanf, i cui prefissi sono SCN.

Altri suggerimenti

Il valore restituito di sizeof è size_t. Se stai usando un compilatore conforme a C99 sembra che tu possa usare %zd % zu per questo.

D'oh: % zu (non firmato) ovviamente. Grazie, ony.

Prima di tutto, dovresti abbinare il "% " identificatore con il tipo di dati effettivo che si desidera stampare. sizeof restituisce il tipo di dati size_t e proprio come non dovresti provare a stampare un float usando un "% d " specificatore, non dovresti provare a stampare size_t con "% u " o "% d " o qualsiasi cosa che non significhi davvero size_t.

Le altre risposte hanno fornito alcuni buoni modi per gestirlo con compilatori più recenti ("% z " e PRIu32), ma il modo in cui lo facevamo era semplicemente di lanciare size_t su unsigned long e quindi stamparlo usando "% lu "

printf("The amount of RAM used is %lu", (unsigned long)(anIntVariable*sizeof(double)) );

Questo non funzionerà su sistemi in cui size_t è più largo di un lungo, ma non conosco nessuno di questi sistemi e non sono nemmeno sicuro che lo standard lo consenta.

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