Pourquoi utiliser #if 0 pour les commentaires de bloc?

Reverse engineering de code et le style me choque un peu, mais je voulais m’assurer qu’il n’y avait aucune bonne raison de faire ces choses …

Est-ce juste moi ou est-ce un style de programmation horrible

if ( pwbuf ) sprintf(username,"%s",pwbuf->pw_name); else sprintf(username,"%d",user_id); 

Et pourquoi un code wrap non destiné à la compilation dans un

 #if 0 .... #endif 

Au lieu de commentaires?


EDIT: Donc, comme certains l’expliquent ci-dessous, cela est dû à la possibilité de flummox / * * / que je n’avais pas réalisé.

Mais je ne comprends toujours pas, pourquoi ne pas simplement utiliser vos outils d’environnement de programmation ou les macros de l’éditeur de texte favori pour bloquer les commentaires en utilisant “//”

Ce ne serait pas beaucoup plus simple et facile à savoir pour sauter visuellement?


Suis-je simplement inexpérimenté en C et ne comprends pas pourquoi ces choses pourraient être une bonne idée – ou n’y a-t-il aucune excuse, et je suis justifié de me sentir irrité par la laideur de ce code?

#if 0 est utilisé assez fréquemment lorsque le bloc supprimé contient des commentaires de bloc

Je ne dirai pas que c’est une bonne pratique, mais je le vois assez souvent.

La déclaration de ligne de contrôle de stream + contrôle est assez facile à comprendre, bien que je l’évite personnellement (et la plupart des directives de codage dans lesquelles j’ai travaillées l’interdisent)

BTW, je modifierais probablement le titre pour être un peu utile “Pourquoi utiliser # si 0 au lieu de bloquer les commentaires”

Si vous avez ce qui suit

 #if 0 silly(); if(foo) bar(); /* baz is a flumuxiation */ baz = fib+3; #endif 

Si vous remplacez naïvement le #if 0 / #endif par /* */ , le commentaire se terminera juste après la flumuxiation, ce qui provoquera une erreur de syntaxe lorsque vous appuierez sur le signe */ à la place du #endif ci-dessus.

EDIT: Une dernière remarque, souvent la syntaxe #if 0 est simplement utilisée lors du développement, en particulier si vous devez supporter plusieurs versions ou dépendances ou plates-formes matérielles. Il n’est pas rare que le code soit modifié pour

 #ifdef _COMPILED_WITHOUT_FEATURE_BAZ_ much_code(); #endif 

Avec un en-tête centralisé définissant (ou non) des centaines de ces constantes #define. Ce n’est pas la plus belle chose au monde, mais chaque fois que je travaillais sur un projet de taille décente, nous utilisions une combinaison de commutateurs d’exécution, de constantes à la compilation (this), de décisions de compilation à la compilation (utilisez simplement différentes. cpp en fonction de la version), et la solution de modèle occasionnelle. Tout dépend des détails.

Bien que vous soyez le développeur qui commence à faire fonctionner la chose, cependant … #if 0 est assez courant si vous n’êtes pas sûr que l’ancien code a toujours une valeur.

Les commentaires sont des commentaires. Ils décrivent le code.

Le code exclu de la compilation est du code, pas des commentaires. Il inclura souvent des commentaires, décrivant le code non compilé pour le moment /

Ce sont deux concepts distincts, et imposer la même syntaxe me semble être une erreur.

Outre le problème lié à l’absence d’imbrication des commentaires de style C, la désactivation de blocs de code avec #if 0 présente l’avantage de pouvoir être réduite si vous utilisez un éditeur prenant en charge le pliage de code. Il est également très facile de le faire dans n’importe quel éditeur, alors que la désactivation de gros blocs de code avec des commentaires de style C ++ peut être compliquée sans le support / les macros de l’éditeur.

En outre, beaucoup de blocs #if 0 ont également un bloc else . Cela permet d’échanger facilement entre deux implémentations / algorithmes et est sans doute moins sujet aux erreurs que de commenter en masse une section et de décommenter une autre. Cependant, vous feriez mieux d’utiliser quelque chose de plus lisible, comme #if DEBUG dans cet événement.

C’est assez idiomatique C juste là. Je ne vois pas ce qui ne va pas avec ça. Ce n’est pas un beau morceau de code, mais il est facile à lire et ce qui se passe et pourquoi, même sans contexte.

Les noms de variables pourraient être meilleurs, et il serait probablement plus sûr d’utiliser snprintf ou peut-être strncpy .

Si vous pensez que cela pourrait être mieux, à quoi préférez-vous ressembler?

Je pourrais faire un léger changement:

 char username[32]; strncpy(username, 30, (pwbuf ? pwbuf->pw_name : user_id)); username[31] = '\0'; 

En ce qui concerne le blocage de commentaires à l’aide de // , une raison à laquelle je peux penser est que, si vous vérifiez ce code dans votre système de contrôle de code source, le journal des reproches vous montrera comme le dernier éditeur pour ces lignes de code. Bien que vous souhaitiez probablement que les commentaires vous soient atsortingbués, le code lui-même vous est également atsortingbué. Bien sûr, vous pouvez revenir en arrière et consulter les révisions précédentes si vous devez consulter le journal des auteurs pour identifier le “véritable” auteur du code, mais cela gagnerait du temps si vous conserviez ces informations dans la révision actuelle.

Évidemment, chacun a sa propre opinion sur ce genre de chose. Alors voici le mien:

Je n’écrirais jamais de code comme ci-dessus, et penserais moins à quiconque l’a fait. Je ne peux pas compter le nombre de fois où les gens pensent qu’il est acceptable de s’en sortir sans attelles de scope, puis d’être mordus par cela.

Mettre l’instruction de contrôle sur la même ligne que le bloc de code est encore pire; l’absence d’indentation rend plus difficile la visualisation du contrôle de stream lors de la lecture. Une fois que vous avez codé pendant quelques années, vous vous habituez à pouvoir lire et interpréter le code rapidement et avec précision, à condition de pouvoir compter sur certains repères visuels. Contourner ces signaux pour des “cas spéciaux” signifie que le lecteur doit s’arrêter et faire une double prise, sans raison valable.

#if (0) , d’autre part, est acceptable au cours du développement, mais doit être supprimé une fois que le code est “stable” (ou au moins remplacez 0 par un nom de symbole significatif du préprocesseur).

Woah là-bas! Ne pas réagir excessivement …

J’appellerais cela plus bâclé pour plus d’espacement inconsistant que toute autre chose. J’ai eu le temps de juger préférable de mettre de courtes déclarations sur la même ligne que leur FI, même si ces affirmations l’étendent.

Le style en ligne est préférable pour la brièveté verticale … pourrait facilement être divisé en 4, plus de lignes

 if (pwbuf) sprintf(username,"%s",pwbuf->pw_name); else sprintf(username,"%d",user_id); 

Personnellement, je déteste le style suivant, car il est si long qu’il est difficile de parcourir un fichier.

 if (pwbuf) { sprintf(username,"%s",pwbuf->pw_name); } else { sprintf(username,"%d",user_id); } 

points ci-dessus noté. Mais les moniteurs étant grand écran et tous, ces jours-ci, cela ne me dérange pas du tout

 if (pwbuf) sprintf(username,"%s",pwbuf->pw_name); else sprintf(username,"%d",user_id); 

Semble toujours avoir trop d’espace horizontal et pas assez d’espace vertical sur mon écran!

De plus, si le bloc de code contient déjà des directives de préprocesseur, n’utilisez pas #if 0 ; si le code a déjà des commentaires de bloc, n’utilisez pas /* */ . S’il possède déjà les deux, vous pouvez soit recourir à un éditeur doté des touches ctrl + / pour mettre en commentaire de nombreuses lignes. Si ce n’est pas le cas, effacez le code!

 if ( pwbuf ) sprintf(username,"%s",pwbuf->pw_name); else sprintf(username,"%d",user_id); 

Idiomatique et concis. Si elle était touchée plus de 2 ou 3 fois, je la mettrais entre crochets et la ligne suivante. Ce n’est pas très maintenable si vous ajoutez des informations de journalisation ou d’autres conditions.

 #if 0 .... #endif 

Bon d’activer ou non des blocs de code de débogage. En outre, éviterait les erreurs de compilation liées à la tentative de blocage des commentaires de ce type:

 /* line comment */ ... /* line comment again */ 

Puisque les commentaires de bloc C ne sont pas nesteds.

J’utilise très occasionnellement le style plus concis lorsqu’il prend en charge la symésortinge du code et que les lignes ne deviennent pas trop longues. Prenons l’exemple artificiel suivant:

 if (strcmp(s, "foo") == 0) { bitmap = 0x00000001UL; bit = 0; } else if (strcmp(s, "bar") == 0) { bitmap = 0x00000002UL; bit = 1; } else if (strcmp(s, "baz") == 0) { bitmap = 0x00000003UL; bit = 2; } else if (strcmp(s, "qux") == 0) { bitmap = 0x00000008UL; bit = 3; } else { bitmap = 0; bit = -1; } 

et la version concise:

 if (strcmp(s, "foo") == 0) { bitmap = 0x00000001UL; bit = 0; } else if (strcmp(s, "bar") == 0) { bitmap = 0x00000002UL; bit = 1; } else if (strcmp(s, "baz") == 0) { bitmap = 0x00000003UL; bit = 2; } else if (strcmp(s, "qux") == 0) { bitmap = 0x00000008UL; bit = 3; } else { bitmap = 0; bit = -1; } 

Les insectes sont beaucoup plus susceptibles de vous sauter au visage.

Avertissement: Cet exemple est artificiel, comme je l’ai dit. N’hésitez pas à discuter de l’utilisation de strcmp, des nombres magiques et de la pertinence d’une approche basée sur des tables. 😉

#if 0 ... #endif est assez commun dans le code C plus ancien. La raison en est que les commentaires avec les commentaires de style C /* .... */ ne fonctionnent pas car les commentaires ne sont pas nesteds.

Même si c’est courant, je dirais qu’il n’a pas sa place dans le code moderne. Les gens le faisaient jadis parce que leurs éditeurs de texte ne pouvaient pas bloquer automatiquement les commentaires de grandes sections. De manière plus pertinente, ils n’avaient pas le contrôle de code source approprié comme nous le faisons maintenant. Il n’y a aucune excuse pour laisser des commentaires ou des # ifdef’d dans le code de production.