2

Cela vient de ma recherche pour une variante intelligente de NSLog(). Une fonctionnalité clé de BetterLog() est que le remplacement NSLog() compile à rien pour les versions de version et de distribution. La solution proposée (voir par exemple Is it true that one should not use NSLog() on production code?) est de définir un symbole de préprocesseur pour contrôler la définition de BetterLog() en fonction du type de construction. En règle générale:Comment éviter les avertissements de compilateur "variable inutilisée" avec des remplacements NSLog conditionnellement compilés?

#ifdef DEBUG_MODE 
    #define DebugLog(s, ...) NSLog(@"<%p %@:(%d)> %@", self, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__]) 
#else 
    #define DebugLog(s, ...) 
#endif 

DEBUG_MODE serait défini comme un symbole de préprocesseur uniquement pour debug.

Toutefois, dans un certain nombre de cas, à savoir lorsque l'instruction de l'exploitation forestière a été construite avec des variables intermédiaires, le résultat est un avertissement du compilateur pour les variables inutilisées. Voici un exemple:

if (error) { 
    NSString *titleString = @"Error downloading thumbnail, will rebuild it"; 
    NSString *messageString = [error localizedDescription]; 
    NSString *moreString = [error localizedFailureReason] ? [error localizedFailureReason] : NSLocalizedString(@"Check the URL.", nil); 
    BetterLog(@"%@: %@. %@", titleString, messageString, moreString); 
} // silently ignoring *this* error is OK. 

Ici toutes les trois chaînes donnent des avertissements de compilateur. Et je déteste les avertissements du compilateur.

Bien sûr, il est impossible d'éviter sans une certaine façon, y compris sous condition les variables elles-mêmes déclarations. J'ai fait la tentative suivante, mais cela n'a pas fonctionné:

au lieu de simplement définir DEBUG_MODE en mode débogage seulement, je le définis tout le temps, avec la valeur 1 en mode de débogage, et la valeur 0 en mode de libération.

Alors j'ai essayé de profiter du compilateur de code mort optimisation stripping:

if (DEBUG_MODE && error) { 
    // snip 
} 

Le code est correct: il est dépouillé correctement en mode de déclenchement. Pourtant, le compilateur émet toujours les avertissements de variable inutilisés.

La question est donc: est-il pas possible de faire mieux que le laid:

#if DEBUG_MODE 
if (error) { 
    // snip 
} 
#endif 

Répondre

1

Une option serait:

#define BetterLog(...) do { (void)(__VA_ARGS__); } while (0) 

Cela a l'avantage que si vous atteignez un BetterLog(), les effets secondaires de ses arguments seront évalués, et c'est une déclaration propre, donc ce n'est pas un bug d'écrire if (x) BetterLog(@"%@", x); (qui briserait la déclaration suivante en utilisant votre macro).

Personnellement, je préfère utiliser l'approche préprocesseur « laid », car il est explicite sur l'exclusion du code de débogage.

+0

Quel est le point de 'while (0)' –

+0

Alexsander, voir la question 10.4 de la FAQ C: http://c-faq.com/cpp/multistmt.html (Erratum: le peu sur "non standard" Le mot-clé inline' est un peu démodé, puisqu'il a été standardisé il y a onze ans.) –

+0

Cela ne fonctionne que si un seul argument est passé, une fois deux passés, je reçois toujours l'avertissement –

Questions connexes