web-dev-qa-db-fra.com

Max (a, b) est-il défini dans stdlib.h ou non?

J'utilise deux ordinateurs, chacun avec une version différente de Visual Studio. Sur mon ordinateur Visual Studio 2008, mon code est compilé. Sur l'ordinateur Visual 2010, mon code n'est pas compilé car j'utilise la macro max(a,b) qui, pour autant que je sache, est définie dans stdlib.h. Je ne peux pas simplement définir max(a,b) car ce sera une redéfinition sur l'ordinateur visual 2008. Mais si je ne définis pas max(a,b), mon code ne sera pas compilé sur l'ordinateur Visual 2010.

Toute solution?

17
snakile

Toute bibliothèque C définissant une macro nommée maxdans ses en-têtes standard est inimaginable. Heureusement, une solution de contournement facile si vous devez prendre en charge de telles plates-formes consiste à #undef maxet à toutes les macros problématiques qu'elle définit) après avoir inclus les en-têtes système et avant tous vos propres en-têtes/codes.

Notez que tout le monde dit d'envelopper votre définition dans #ifndef max ... #endif. C'est _ (pasune bonne idée. Définir maxdans un en-tête système indique que l'implémenteur était incompétent, et il est possible que certaines versions de l'environnement aient incorrect macros (par exemple, celles qui ne protège pas correctement les arguments entre parenthèses, mais j’ai même vu une macro maxqui exécutait incorrectement minau lieu de maxau moins une fois dans ma vie!). Utilisez simplement #undef et soyez en sécurité.

En ce qui concerne la raison pour laquelle stdlib.h définit maxname__, le standard C spécifie très précisément quels noms sont réservés pour l'application et quels noms sont réservés pour des fonctions standard et/ou à usage interne par l'implémentation. Il y a de très bonnes raisons pour cela. Définir des noms de macro dans les en-têtes système susceptibles d'entrer en conflit avec les noms de variable/fonction utilisés dans le programme d'application est dangereux. Dans le meilleur des cas, cela entraîne des erreurs de compilation ayant une cause évidente, mais dans d'autres cas, cela peut entraîner un comportement très étrange et difficile à déboguer. Dans tous les cas, il est très difficile d’écrire du code portable car on ne sait jamais quels noms seront déjà pris par la bibliothèque.

28
R..

Donc, répondant à votre question principale:

Max (a, b) est-il défini dans stdlib.h ou non?

Non ce n'est pas, c'est défini dans windef.h autour de la ligne 187:

#ifndef NOMINMAX

#ifndef max
#define max(a,b)            (((a) > (b)) ? (a) : (b))
#endif

#ifndef min
#define min(a,b)            (((a) < (b)) ? (a) : (b))
#endif

#endif  /* NOMINMAX */
4
Calmarius

Protégez-le avec un #ifndef

#ifndef max
    #define max(a,b) ((a) > (b) ? (a) : (b))
#endif

N'oubliez pas que la version ci-dessus n'est pas aussi sûre qu'une fonction en ligne, par ex. max(a++,b--) entraînera des résultats inattendus.

4
John Ledbetter

vous pouvez utiliser la compilation de conditions:

#ifndef max
  #define max(a,b) ...
#endif
0
Vladimir Ivanov

Dans Visual C++, si vous #define NOMINMAX avant d'inclure les en-têtes standard, vous n'obtiendrez pas de macro max ou min.

0
Bill Lynch