140 votes

Spécification de NSLog/printf pour NSInteger ?

A NSInteger est de 32 bits sur les plateformes 32 bits, et de 64 bits sur les plateformes 64 bits. Existe-t-il un NSLog qui correspond toujours à la taille de NSInteger ?

Configuration

  • Xcode 3.2.5
  • Compilateur llvm 1.6 (ceci est important ; gcc ne le fait pas)
  • GCC_WARN_TYPECHECK_CALLS_TO_PRINTF allumé

C'est ce qui me cause des ennuis :

#import <Foundation/Foundation.h>

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

Pour le code 32 bits, j'ai besoin du %d . Mais si j'utilise le %d je reçois un avertissement lors de la compilation pour 64 bits suggérant d'utiliser le spécificateur %ld à la place.

Si j'utilise %ld pour correspondre à la taille 64 bits, lorsque je compile pour du code 32 bits, j'obtiens un avertissement me suggérant d'utiliser %d à la place.

Comment puis-je corriger les deux avertissements en même temps ? Existe-t-il un spécificateur que je peux utiliser et qui fonctionne sur les deux ?

Cela a également un impact sur [NSString stringWithFormat:] y [[NSString alloc] initWithFormat:] .

309voto

Kevin Ballard Points 88866

Réponse actualisée :

Vous pouvez utiliser le z y t modificateurs pour traiter NSInteger y NSUInteger sans avertissement, sur toutes les architectures.

Vous voulez utiliser %zd pour signé, %tu pour les non signés, et %tx pour l'hexagone.

Cette information est une courtoisie de Greg Parker .


Réponse originale :

El l'approche officielle recommandée est d'utiliser %ld en tant que spécificateur, et de mettre l'argument réel dans un long .

6 votes

C'est définitivement la voie à suivre, mais je pense que je pourrais utiliser static inline NSIntToLong(NSInteger i) {return (long)i;} . Cela évite de désactiver complètement la vérification du type (c'est-à-dire si le type de i change).

3 votes

Bien pensé par @steven-fisher. Éviter l'avertissement avec : static inline long NSIntToLong(NSInteger i) {return (long)i;}

3 votes

Vous pouvez également créer un numéro NSN et l'enregistrer. NSLog(@"%@",@(mynsint)); stackoverflow.com/questions/20355439/

3voto

gnasher729 Points 5011

La réponse acceptée est absolument raisonnable, elle est conforme à la norme et correcte. Le seul problème est qu'elle ne fonctionne plus, ce qui est entièrement la faute d'Apple.

Le format %zd est le format standard C/C++ pour size_t et ssize_t. Comme NSInteger et NSUInteger, size_t et ssize_t sont 32 bits sur un système 32 bits, et 64 bits sur un système 64 bits. Et c'est pourquoi l'impression de NSInteger et NSUInteger à l'aide de %zd a fonctionné.

Cependant, NSInteger et NSUInteger sont définis comme "long" sur un système 64 bits, et comme "int" sur un système 32 bits (qui est 64 vs 32 bits). Aujourd'hui, size_t est défini sur "long" sur tous les systèmes, ce qui es de la même taille que NSInteger (64 ou 32 bits), mais d'un type différent. Soit les avertissements d'Apple ont changé (de sorte qu'ils ne permettent pas de passer le mauvais type à printf, même s'il a le bon nombre de bits), soit les types sous-jacents de size_t et ssize_t ont changé. Je ne sais pas lequel des deux, mais %zd a cessé de fonctionner il y a quelque temps. Il y a pas de qui imprimera NSInteger sans avertissement sur les systèmes 32 et 64 bits.

Donc la seule chose que vous pouvez faire malheureusement : Utiliser %ld et convertir vos valeurs de NSInteger en long, ou de NSUInteger en unsigned long.

Une fois que vous ne construisez plus pour le 32 bit, vous pouvez simplement utiliser %ld, sans aucun casting.

1voto

cat Points 726

Les formateurs proviennent de la fonction printf standard d'UNIX/POSIX. Utilisez %lu para long non signé , %ld pour long, %lld pour long long, et %llu para non signé long long . Essayez man printf sur la console, mais sur Mac c'est incomplet. Les manpages linux sont plus explicites http://www.manpages.info/linux/sprintf.3.html

Les deux avertissements ne peuvent être corrigés que par NSLog(@"%lu", (unsigned long)arg) ; combiné avec un cast car le code sera compilé en 32 ET 64 bit pour iOS. Sinon, chaque compilation crée un avertissement distinct.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X