56 votes

Pourquoi l'opération (void) 0 est-elle interdite en C et C++ ?

J'ai vu des impressions de débogage dans glibc qui, en interne, est défini comme suit (void) 0 si NDEBUG est définie. De même, le __noop pour le compilateur Visual C++ est là aussi. Le premier fonctionne à la fois sur les compilateurs GCC et VC++, tandis que le second ne fonctionne que sur VC++. Maintenant, nous savons tous que les deux déclarations ci-dessus seront traitées comme une absence d'opération et aucun code respectif ne sera généré ; mais voici où j'ai un doute.

En cas de __noop MSDN dit que c'est une fonction intrinsèque fournie par le compilateur. Venant à (void) 0 ~ Pourquoi est-il interprété par les compilateurs comme un no op ? Est-ce une utilisation délicate du langage C ou la norme dit-elle quelque chose à ce sujet explicitement ? Ou même que c'est quelque chose à faire avec l'implémentation du compilateur ?

75voto

Alexander Gessler Points 26717

(void)0 (+ ; ) est une expression C++ valide, mais qui ne fait rien, c'est tout. Elle ne se traduit pas par l'expression no-op de l'architecture cible, il s'agit simplement d'une déclaration vide qui sert de substitut lorsque le langage attend une déclaration complète (par exemple comme cible d'une étiquette de saut, ou dans le corps d'une instruction de type if clause).

EDIT : (mise à jour basée sur le commentaire de Chris Lutz)

Il convient de noter que lorsqu'il est utilisé comme une macro, par exemple

#define noop ((void)0)

le site (void) empêche qu'il soit accidentellement utilisé comme une valeur comme

int x = noop;

Pour l'expression ci-dessus, le compilateur la signalera à juste titre comme une opération invalide. Le GCC crache error: void value not ignored as it ought to be et VC++ aboie 'void' illegal with all types .

10voto

Toute expression qui n'a pas d'effets secondaires peut être traitée comme un no-op par le compilateur, qui n'est pas obligé de générer du code pour elle (bien qu'il le puisse). Il se trouve que le fait d'effectuer un casting et de ne pas utiliser le résultat du cast est facile pour le compilateur (et les humains) à voir comme n'ayant pas d'effets secondaires.

3voto

Alok Singhal Points 33073

Je pense que vous parlez de glibc pas glib et la macro en question est la assert macro :

Dans le fichier de la glibc <assert.h> avec NDEBUG (pas de débogage) défini, assert est défini comme suit :

#ifdef NDEBUG
#if defined __cplusplus && __GNUC_PREREQ (2,95)
# define __ASSERT_VOID_CAST static_cast<void>
#else
# define __ASSERT_VOID_CAST (void)
#endif
# define assert(expr)           (__ASSERT_VOID_CAST (0))
#else
/* more code */
#endif

ce qui signifie essentiellement assert(whatever); est équivalent à ((void)(0)); et ne fait rien.

Extrait de la norme C89 (section 4.2) :

L'en-tête <assert.h> définit le assert et fait référence à une autre macro,

NDEBUG

qui n'est pas défini par <assert.h> . Si NDEBUG est défini comme un nom de macro au point du fichier source où <assert.h> est inclus, le assert est définie simplement comme suit

#define assert(ignore) ((void)0)

Je ne pense pas que définir une macro d'impression de débogage pour qu'elle soit égale à (void)0 a beaucoup de sens. Pouvez-vous nous montrer où cela se fait ?

1voto

Darko Maksimovic Points 194

Même si c'est le cas, pourquoi le convertir en void ? De même, dans le cas du #define dbgprintf (void) 0, lorsqu'il est appelé comme dbgprintf("Hello World !") ; -> (void) 0("Hello World !") ; - qu'est-ce que cela signifie ? - légendes2k

Les macros remplacent votre code par quelque chose d'autre, donc si vous #définissez dbgprint (qui accepte x) en tant que

void (0)

alors aucune réécriture de X ne se produira dans le remplacement, ainsi dbgprintf("Helloworld") ne sera pas converti en (void) 0("Hello world"), mais en (void) 0 ; - non seulement le nom de la macro dbgprint est remplacé par (void) 0, mais l'appel entier dbgprintf("...")

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X