Domanda

UN NSInteger è 32 bit su piattaforme a 32 bit e 64 bit su piattaforme a 64 bit.C'è un NSLog specificatore che corrisponde sempre alla dimensione di NSInteger?

Impostare

  • Xcodice 3.2.5
  • compilatore lvm 1.6 (questo è importante;gcc non lo fa)
  • GCC_WARN_TYPECHECK_CALLS_TO_PRINTF acceso

Questo mi sta causando un po' di dolore qui:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    @autoreleasepool {
        NSInteger i = 0;
        NSLog(@"%d", i);
    }
    return 0;
}

Per il codice a 32 bit, ho bisogno del file %d specificatore.Ma se utilizzo il %d specificatore, ricevo un avviso durante la compilazione per 64 bit che suggerisce di utilizzare %ld Invece.

Se uso %ld per corrispondere alla dimensione a 64 bit, durante la compilazione per il codice a 32 bit ricevo un avviso che suggerisce di utilizzare %d Invece.

Come posso correggere entrambi gli avvisi contemporaneamente?C'è uno specificatore che posso usare che funzioni su entrambi?

Anche questo incide [NSString stringWithFormat:] E [[NSString alloc] initWithFormat:].

È stato utile?

Soluzione

Risposta aggiornata:

Con l'attuale Xcode, puoi utilizzare il file z E t modificatori da gestire NSInteger E NSUInteger senza preavviso, su tutte le architetture.

Vuoi usare %zd per firmato, %tu per non firmato e %tx per esadecimale.

Questa informazione viene per gentile concessione di Greg Parker.


Risposta originale:

IL approccio raccomandato ufficiale è usare %ld come specificatore e per trasmettere l'argomento effettivo a a long.

Altri suggerimenti

I formattatori provengono dalla funzione printf UNIX / POSIX standard. Usa % lu per unsigned long ,% ld per lungo tempo,% LLD per molto tempo, e % llu per unsigned long long . Prova uomo printf sulla console, ma su Mac è incompleta. Le pagine di manuale di Linux sono più espliciti http://www.manpages.info/linux/sprintf.3 .html

I due avvisi possono essere fissati solo da NSLog (@ "% lu", (unsigned long) arg); combinato con un getto come il codice verrà compilato in 32 e 64 bit per IOS. In caso contrario, ogni compilazione crea un avviso separato.

La risposta accettata è assolutamente ragionevole, è conforme standard e corretta. L'unico problema è che non funziona più, che è completamente colpa di Apple.

L'% zd formato è formato standard del C / C ++ per size_t e ssize_t. Come NSInteger e NSUInteger, size_t e ssize_t sono a 32 bit su un sistema a 32 bit e 64 bit su un sistema a 64 bit. Ed è per questo la stampa NSInteger e NSUInteger usando% zd funzionato.

Tuttavia, NSInteger e NSUInteger sono definiti come "lunga" a un sistema a 64 bit, e come "int" a un sistema a 32 bit (che è 64 vs 32 bit). Oggi, size_t è definita "lunga" a tutti i sistemi, che è le stesse dimensioni NSInteger (64 o 32 bit), ma un tipo diverso. In entrambi gli avvertimenti di Apple sono cambiati (in modo che non consente il passaggio il tipo sbagliato di printf, anche se ha il giusto numero di bit), oi tipi sottostanti per size_t e ssize_t sono cambiati. Non so quale, ma% ZD ha smesso di funzionare qualche tempo fa. C'è non formato oggi che stamperà NSInteger senza preavviso su entrambi i sistemi a 32 e 64 bit.

Quindi l'unica cosa che si può fare, purtroppo: Uso% ld, e gettato i vostri valori da NSInteger a lungo, o da NSUInteger a unsigned long.

Una volta non costruire per 32 bit più, si può semplicemente utilizzare% ld, senza alcun cast.

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