Comment utiliser des constantes typées avec des avertissements «variable inutilisée»?

J’utilise Xcode 4.6 et j’ai un fichier d’en-tête qui inclut certaines constantes que j’utilise dans tout mon code. Je ne veux pas utiliser les directives de préprocesseur parce que je veux qu’elles soient correctement typées, etc.

Par exemple, j’ai ce code dans l’un de mes fichiers .h:

static NSSsortingng *kErrorCannotDivideByZero = @"Error: Cannot divide by zero"; 

et je l’utilise dans le fichier .m correspondant:

 [self showToast:kErrorCannotDivideByZero]; 

Je reçois l’avertissement:

 /path/to/my/headerFile.h:32:18: Unused variable 'kErrorCannotDivideByZero' 

Je sais que ce n’est qu’un avertissement, mais environ 50 de ces avertissements encrassent la sortie de mon compilateur.

Pourquoi ai-je cet avertissement et comment puis-je le résoudre correctement?

Je ne souhaite pas simplement supprimer tous les avertissements de variable non utilisés, car je souhaite obtenir les avertissements légitimes.

Faites la déclaration dans votre en-tête extern plutôt que static . Ce que vous faites, c’est créer une variable pour chaque unité de traduction qui inclut votre en-tête. C’est pourquoi Clang vous avertit, car il s’agit légitimement d’une variable définie qui n’est pas utilisée. Le mot-clé extern indique au compilateur que la définition de la variable se trouve ailleurs (cela peut être dans la même unité de traduction ou dans une autre).

Dans votre en-tête, avez:

 // declare that the constant exists somewhere extern NSSsortingng * const kErrorCannotDivideByZero; 

Et dans l’ un de vos fichiers .m (généralement celui qui partage le même nom que l’en-tête), mettez

 // define the constant, ie this is where it exists NSSsortingng * const kErrorCannotDivideByZero = @"Error: Cannot divide by zero"; 

La déclaration de variables extern permet au compilateur de s’assurer que vous traitez correctement la variable même s’il ne sait pas où elle est définie (par exemple, vous ne pouvez pas l’utiliser en tant que NSArray ). L’éditeur de liens a pour tâche de s’assurer que vous l’avez bien défini quelque part.

Clang vous permettra de pousser et de faire apparaître des drapeaux d’avertissement sur et depuis une stack de “diagnostics”: “Contrôle des diagnostics via des pragmas” . Vous pouvez envelopper certains morceaux de code comme ceci:

 #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-variable" static NSSsortingng *kErrorCannotDivideByZero = @"Error: Cannot divide by zero"; #pragma clang diagnostic pop 

pour dire à Clang que vous savez que ceux-ci ne sont pas utilisés, et ce n’est pas grave dans ce cas particulier.

Incidemment, il se peut que vous ne souhaitiez pas définir ces variables dans un fichier importé à différents endroits – c’est un bon moyen de provoquer des erreurs d’éditeur de liens concernant la redéfinition des variables (bien que cela ne se produise si la variable était liée globalement – déclarée / définie sans static ). Le modèle habituel pour les constantes de ce type consiste à placer une déclaration extern dans l’en-tête et à définir la variable dans un autre fichier. Voir Référencement d’une NSSsortingng * const statique à partir d’une autre classe pour plus de détails.

Comme Dreamlax l’a fait remarquer, vous recevez ces avertissements, car chaque fichier qui importe votre en-tête reçoit sa propre copie de la variable static ; Lorsque j’ai suggéré la technique #pragma ci-dessus, je ne comprenais pas ce que vous demandiez.

Faites vos constantes constantes:

 static NSSsortingng * const kErrorCannotDivideByZero = @"Error: Cannot divide by zero"; 

(et comme d’autres l’ont souligné, utilisez extern et définissez-le dans le fichier d’implémentation)

Plutôt que de les initialiser à des littéraux de chaîne, vous pourriez peut-être exécuter une fonction d’initialisation qui charge ces valeurs à partir d’un fichier spécifique à l’environnement local afin que les erreurs soient dans une langue traduite. Lorsque votre fonction d’initialisation affecte cette variable, votre compilateur peut être tenté de croire que la variable doit exister pour que la compilation réussisse.

GCC (et je suppose que clang) ne met pas en garde sur les constantes non utilisées. Un piège à surveiller ici est que les pointeurs doivent être des pointeurs const, et pas seulement des pointeurs sur const; donc, pour déclarer correctement une constante de chaîne inutilisée qui ne déclenchera aucun avertissement, vous avez besoin des éléments suivants:

 const char * const myConst = "myConst"; 

Vous pouvez déplacer toute la déclaration de variable statique dans votre fichier .m respectif. Cela devrait enlever tous ces avertissements de “variable non utilisée”. La raison en est que les variables statiques sont limitées à une scope de niveau fichier.