Duplicates possibles: strong>
Pourquoi y a-t-il parfois Sans signification DO / PENDANT DES MACRES C / C ++?
do {...} tandis que c'est bon? a> p>Je travaille sur certains Code C rempli de macros comme ceci: p>
#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0)
4 Réponses :
Le processus est une convention commune qui rend la macro nécessite un demi-côlon de fin comme une fonction C standard. Autre que cela garantit simplement la variable libérée est définie sur NULL afin que tous les appels futurs pour libérer ne causeront pas d'erreurs. P>
Wow, maintenant que vous l'expliquez de cette façon, cela est parfaitement logique.
Excellent. J'ai vu le do {} alors que (0) code> bit avant mais jamais compris pourquoi.
Cela n'a pas seulement du sens, mais si vous avez un très bon compilateur, il devrait optimiser la boucle. Je ne sais pas si quelque chose comme MSVC, GCC, ICC, LCC, etc. Enlevez la boucle comme si elles devraient, mais l'optimisation est sûrement un problème difficile à résoudre en matière de compilation de code. : P
Le point principal sur DO / TIX (0) est d'éviter un code élargi qui est très différent de l'intention du programmeur.
@janm qui peut être accompli en utilisant simplement des accolades sans avoir besoin de la recherche inutile / tandis que (0). Par exemple #define Safe_free (x) {if ((x)! = Null) {free (x); x = null;}} code>
@Brandon bodnár: Non. Considérons "Si (test) Safe_free (x); sinon bla ();" Erreur de syntaxe instantanée.
@Brandonbodnar mise en parenthèse autour d'un bloc de code ({/ * ... * /}) code> est analysé comme une seule expression sur la plupart des compilateurs de nos jours, mais il est non standard dans ANSI C (je pense que c90 a fixé ceci )
EDIT: C90 ne résout pas ceci: c
if (...)
if ((x) != NULL) {
free(x);
x = NULL;
} else
stuff();
W.R.T "Je ne sais pas si cela ressemble à MSVC, GCC, ICC, LCC, etc. Enlevez la boucle comme si elles devraient, mais l'optimisation est sûrement un problème difficile à résoudre en ce qui concerne la compilation de code." Vous n'avez même pas besoin d'un compilateur particulièrement bon. C'est un tel constructeur courant que GCC l'optimise même avec des optimisations désactivées. Ce n'est même pas une optimisation - quelque chose à faire fonctionner le code plus rapide - en soi: juste une élimination triviale de la syntaxe inutile.
GCC n'impose pas cela avec des optimisations désactivées. GCC ne fait rien qui restructure votre code lorsque des optimisations sont désactivées, sinon le débogage serait un cauchemar.
@Jason COO: Euh ... oui ça fait. Vérifié un exemple simple avec et sans le "do {...} tandis que (0);" wrapper, avec -O0 et les options par défaut. GCC me donne exactement la même sortie. (4.3.2, Debian 4.3.2-1.1, sur Debian Lenny.)
Pourquoi ne pas utiliser qu'un bloc? Il semble que le fait (0) est toujours redondant et pourrait être accompli avec un ensemble d'accolades frisées, comme indiqué dans le code ci-dessus. Le point-virgule est la seule raison du moment que je puisse voir.
@Jason Comment débiterait-il de devenir un cauchemar?
L'idée derrière le do / tandis (0) est que vous pouvez utiliser la macro où vous utiliseriez un appel de fonction sans erreur inattendue.
Par exemple, si vous aviez du code comme: P>
#define SAFE_FREE(x) if (x) { free(x); x = 0; }
BTW sur le C ++ style et technique FAQ Bjarne Stroustrup suggère d'utiliser une fonction inline (modèle) pour faire un "Supprimer et NULL"
template<class T> inline void destroy(T*& p) { delete p; p = 0; }
Ce serait génial si c avait des modèles :)
@jmh lol, pourquoi? Void * Code> Course de maître.
Où est ce code C utilisé? De quoi s'agit-il?
Dupliquer: Stackoverflow.com/questions/154136
Un problème avec cette macro particulière: quelque chose comme
Safe_free (get_buffer ()) code> ne compilera pas. Quelque chose à penser lors de la création de macros comme celle-ci.si ((x)! = null) code> est redondant. Vous pouvez le supprimer en toute sécurité.Gratuit (NULL) CODE> Ne fait rien, alors pourquoi gaspiller unsi code> sur elle?@Dan moulage: c'est le point de la construction - il nécessite un point-virgule, il semble donc comme un appel de fonction.
@JEfromi: Dan ne parle pas du point-virgule suivant, il souligne que vous ne pouvez pas transmettre une r devalue.
@N 1.1: Pourquoi perdre une fonction d'appel si vous n'avez pas aussi? Matière de préférence.
@ N1.1 libre (null); est un comportement indéfini et simplement parce que tous les systèmes d'exploitation modernes vérifient cela ne signifie pas que c'est sûr.
@Yoyoyonny qui est incorrect
si PTR est un pointeur nul, aucune action ne se produit. Code> est dans la norme C à la section §7.20.3.2.2.2