Определяется ли max (a, b) в stdlib.h или нет? - PullRequest
18 голосов
/ 20 ноября 2010

Я использую два компьютера, каждый с разной версией Visual Studio.На компьютере visual studio 2008 мой код компилируется.На компьютере Visual 2010 мой код не компилируется, потому что я использую макрос max(a,b), который, насколько я знаю, определен в stdlib.h.Я не могу просто определить max(a,b), потому что это будет переопределение на компьютере Visual 2008.Но если я не определю max(a,b), мой код не скомпилируется на компьютере Visual 2010.

Есть ли какое-нибудь решение?

Ответы [ 5 ]

30 голосов
/ 20 ноября 2010

Любая библиотека C, которая определяет макрос с именем max в своих стандартных заголовках, выходит за рамки воображения.К счастью, простой способ обойти эту проблему, если вам требуется поддержка таких платформ, - #undef max (и любые другие проблемные макросы, которые он определяет) после включения системных заголовков и перед любым из ваших собственных заголовков / кода.

Обратите внимание, что каждыйеще говорит обернуть ваше определение в #ifndef max ... #endif.Это не хорошая идея.Определение max в системном заголовке указывает на то, что разработчик некомпетентен, и вполне возможно, что определенные версии среды имеют макросы некорректные (например, те, которые не защищают аргументы с помощью круглых скобок, ноЯ даже видел макрос max, который неправильно выполнял min вместо max хотя бы раз в жизни!).Просто используйте #undef и будьте в безопасности.

Что касается того, почему stdlib.h так не подходит для определения max, стандарт C очень конкретен относительно того, какие имена зарезервированы для приложения и какие имена зарезервированыдля стандартных функций и / или внутреннего использования реализацией.Для этого есть очень веские причины.Определение имен макросов в системных заголовках, которые могут конфликтовать с именами переменных / функций, используемых в прикладной программе, опасно.В лучшем случае это приводит к ошибкам во время компиляции с очевидной причиной, но в других случаях это может вызвать очень странное поведение, которое трудно отладить.В любом случае это очень затрудняет написание переносимого кода, потому что вы никогда не знаете, какие имена уже будут заняты библиотекой.

5 голосов
/ 26 мая 2014

Итак, отвечая на ваш главный вопрос:

Определен ли max (a, b) в stdlib.h или нет?

Нет, не определен, он определенв windef.h вокруг строки 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 */
3 голосов
/ 20 ноября 2010

Защитите его с помощью #ifndef.

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

Имейте в виду, что приведенная выше версия не так безопасна, как встроенная функция, например, max(a++,b--) приведет к неожиданным результатам.

0 голосов
/ 20 ноября 2010

В Visual C ++, если вы добавите #define NOMINMAX до включения стандартных заголовков, вы не получите макрос max или min.

0 голосов
/ 20 ноября 2010

Вы можете использовать условие компиляции:

#ifndef max
  #define max(a,b) ...
#endif
...