Si le nom de la fonction est absent, comme dans votre premier exemple, ce n'est pas un "opérateur parenthèse". C'est simplement un élément syntaxique d'une expression qui modifie l'association entre opérateurs et opérandes. Dans ce cas, cela ne fait rien. Qu'est-ce que vous avez est juste une expression
"Hello world";
qui évalue à une valeur de type char *
, et cette valeur est ignorée. Vous pouvez entourer cette expression dans une paire redondante de ()
("Hello world");
qui ne changera rien.
exactement de la même façon que vous pouvez écrire
(5 + 3);
au milieu de votre code et d'obtenir une expression qui évalue la valeur 8
, qui est immédiatement mis au rebut.
Habituellement, les compilateurs ne génèrent aucun code pour les instructions d'expression qui n'ont pas d'effets secondaires. En fait, dans le langage C, le résultat de chaque instruction d'expression est supprimé, de sorte que les seules instructions d'expression qui ont un sens sont des instructions d'expression avec des effets secondaires. Les compilateurs sont normalement assez bons pour détecter des déclarations sans effet et les rejeter (parfois avec un avertissement).
L'avertissement pourrait être gênant, l'écriture si les instructions d'expression effectless comme
"Hello world";
pourrait ne pas être une bonne idée. compilateurs généralement reconnaître une distribution à void
comme une demande de ne pas générer cet avertissement
(void) "Hello world";
Alors vous pourriez envisager de redéfinir votre macro en conséquence.
Bien sûr, en utilisant la technique trace
ci-dessus, vous devez vous rappeler que si vous mettez quelque chose qui ne ont un effet secondaire comme argument pour votre macro
trace("%d\n", i++);
alors en forme « désactivé » il se présentera comme suit
("%d\n", i++);
(deux sous-expressions, chaînées par une virgule dans une expression). L'effet secondaire de l'incrémentation i
persiste dans ce cas, il n'est pas désactivé.Le tout est équivalent à la plaine
i++;
Aussi, si vous utilisez un appel de fonction comme un argument
trace(get_trace_name());
la forme « disabled » regardera comme
(get_trace_name());
et le compilateur peut ne pas être assez intelligent pour se rendre compte que l'appel à get_trace_name()
doit être ignoré. Alors, soyez prudent lorsque vous utilisez votre macro. Évitez les arguments avec effets secondaires, évitez les arguments avec appels de fonction, à moins, bien sûr, que vous ayez l'intention de préserver les effets secondaires lors de la désactivation du suivi réel.
Un point un peu délicat avec des macros multi-instructions comme ceci est qu'ils ne fonctionnent pas comme ils peuvent apparaître avec des choses comme instructions 'if' (vous ne devez pas dire quelque chose comme' if (condition) TRACE ("mauvais"); ') - peut-être pourriez-vous corriger ceci en utilisant' && 'à la place du point-virgule (?) - ou soyez prudent en utilisant la macro;) –