Этот вопрос не совпадает с одним из них:
Я использую Windows 7 и Visual Studio Express 2012, но не ожидаю, что ни один из них не повлияет на ответ на этот вопрос.
tl; dr. Как мне лучше всего противодействовать / предотвращать / терпеть последствия следующего отрывка из math.h, в то же время позволяя компилировать его с Visual C ++?
#if !__STDC__
/* Non-ANSI names for compatibility */
#define DOMAIN _DOMAIN
#define SING _SING
#define OVERFLOW _OVERFLOW
#define UNDERFLOW _UNDERFLOW
#define TLOSS _TLOSS
#define PLOSS _PLOSS
#define matherr _matherr
Предыстория: я пишу увлекательный текстовый проект C ++, общие цели которого выходят далеко за рамки этого вопроса. Я использую GNU Make (для удобства и переносимости), чтобы скомпилировать его с Cygwin g ++ и cl.exe, и предполагаю, что среда строго соответствует стандартам … пока что. Я начинаю думать, что Windows просто не допускает такого предположения.
У меня есть перечисление, члены которого включают OVERFLOW
а также UNDERFLOW
, Описанная ниже проблема грозит заставить меня изменить эти имена, но я бы предпочел оставить их, потому что они наиболее подходят для моих целей, несмотря на внешние воздействия, такие как заголовочные файлы Windows.
Заголовочные файлы GCC, Visual C ++ и Mac OS X (независимо от llvm-gcc) все определяют OVERFLOW
а также UNDERFLOW
среди других нестандартных макросов в math.h по умолчанию.
_POSIX_C_SOURCE
) совпадает с документацией GCC. (Я упоминаю об этом в интересах компенсации отсутствия документации Apple; у меня есть история с этими идентификаторами.)__STDC__
макро) предотвращения определения немного нестандартные макросы в Visual C ++. Как показано в начале этого вопроса, __STDC__
макрос также мешает определению OVERFLOW
а также UNDERFLOW
,Обнаружив, что ключ / u будет препятствовать определениям, которые меня интересуют, я добавил его в свой make-файл. Но потом я получил новую ошибку из строки 44 файла crtdefs.h:
error C1189: Only Win32 target supported!
Это потому что _WIN32
больше не определяется. Немного поиска показало, что crtdefs.h связан с Windows Driver Development Kit. Я не занимаюсь разработкой драйвера; могу ли я как-то не использовать этот заголовок? Или мне просто нужно переименовать мои члены enum, чтобы терпеть нестандартное поведение Windows?
Вместо использования /u
переключатель компилятора, который имеет несколько эффектов, просто используйте /D__STDC__=1
что вызывает __STDC__
макрос, который будет определен, и ничего больше.
На ум приходят две возможности.
Во-первых, убедитесь, что вы меняете конкретные эффекты, когда вы включаете math.h
с чем-то вроде:
#include <math.h>
#undef OVERFLOW
#undef UNDERFLOW
Теперь, это может также вызвать проблемы где-нибудь с кодом, который ожидает, что эти вещи будут определены правильно. Однако даже в этом случае вы можете изменить свое программное обеспечение, чтобы использовать другое имя для math.h
из них:
#include <math.h>
#undef OVERFLOW
#undef UNDERFLOW
#define MATH_H_OVERFLOW _OVERFLOW
#define MATH_H_UNDERFLOW _UNDERFLOW
Вам просто нужно убедиться, что весь исходный код (уже скомпилированный код, такой как библиотеки) не имеет значения), который хочет использовать math.h
те, использования MATH_H_*
константы вместо тех, что в вашем перечислении.
Во-вторых, нужно очень тщательно подумать о том, сколько усилий вы вкладываете в этот квест, по сравнению с количеством усилий, которое потребуется для простого переименования вашего квеста. enum
члены к чему-то, что не конфликт. Что-то вроде использования Overflow
для вашего перечисления (вместо OVERFLOW
) будет моей первой попыткой, поскольку в обоих случаях все равно остается одинаковое количество информации, и это устраняет непосредственный конфликт.
Да я знаю что будет отлично чтобы найти способ, который не требует этого, но вы должны заниматься поставкой программного обеспечения, а не тратить непомерное количество времени на обход мелких мелочей в своей среде 🙂
В C ++ 11 вы можете использовать объемные перечисления:
enum class Flows { Underflow, Overflow };
Теперь вы ссылаетесь на Flows :: Underflow и Flows :: Overflow.
Даже в C ++ 98 рекомендуется использовать симуляцию с классами:
class Flows
{
public:
enum Value { Underflow, Overflow };
};