Является ли max (a, b) определенным в stdlib.h или нет?

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

Любое решение?

Ответы

Ответ 1

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

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

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

Ответ 2

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

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

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

Ответ 3

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

Является 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 */

Ответ 4

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

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

Ответ 5

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