Как удалить приведение в стиле C из #define, чтобы я мог использовать его в препроцессоре #if?

Я хотел бы использовать следующий препроцессор определяет:

[заголовок третьей стороны (не может изменить)]

#define SWCI_VERSION_MAJOR              (unsigned char) 4
#define SWCI_VERSION_MINOR              (unsigned char) 16

когда они сравниваются следующим образом:

[реализации]

#if SWCI_VERSION_MAJOR >= 4 && SWCI_VERSION_MINOR >= 16

тогда я получаю:

неустранимая ошибка C1017: недопустимое целочисленное постоянное выражение

Я заметил, что если я определяю их без (без знака char) директива будет принята, но у меня нет доступ к определениям, поэтому я хотел бы обойти эту проблему, если это возможно.

4 ответов


вы можете заставить это работать с небольшой магией препроцессора. Из-за того, как препроцессор применяет макросы, иногда можно выполнить некоторые изменения с помощью нескольких макроуровней. Повышение.Препроцессор использует это поведение. Этот код использует тот факт, что (unsigned char) похоже, что можно сделать вызов макроса, добавив имя макроса X который ничего не оценивает, оставляя только конечный номер.

#define SWCI_VERSION_MAJOR              (unsigned char) 4
#define SWCI_VERSION_MINOR              (unsigned char) 16

#define X(unused)
#define APPLY(x) x

#define MAJOR (APPLY(X SWCI_VERSION_MAJOR))
#define MINOR (APPLY(X SWCI_VERSION_MINOR))

#if MAJOR >= 4 && MINOR >= 16
#error "Version is greater or equal to 4.16"
#endif

посмотреть https://goo.gl/GOsLDL пример #if оценка true и печать #error сообщение я добавил.


возможно, использование функции constexpr сделает трюк? Что-то вроде

constexpr bool version_supported(const char major, const char minor)
{
    return major >= 4 && minor >= 16;
}
constexpr VERSION_SUPPORTED = version_supported(SWCI_VERSION_MAJOR, SWCI_VERSION_MINOR);

проблема в том, что вы не можете использовать эти макросы как собственные числа. В зависимости от того, что вы хотите сделать внутри if блок, вы можете рассмотреть вопрос о том, чтобы сделать его непереработанным оператором:

// Note the next line does not start with a #
if((unsigned int)SWCI_VERSION_MAJOR >= 4 && (unsigned int)SWCI_VERSION_MINOR >= 16) 
{
  // ...
}

но это работает только, конечно, если вы используете его внутри функции и содержание if block не являются операторами препроцессора, такими как defines.


просто рассмотрим следующее

#define SWCI_VERSION_MAJOR              (unsigned char) 4
#define SWCI_VERSION_MINOR              (unsigned char) 16

при использовании в следующем выражении:

#if SWCI_VERSION_MAJOR >= 4 && SWCI_VERSION_MINOR >= 16

это будет преобразовано (препроцессором) в следующее #if (unsigned char) 4 > 4

проблема в том, что это выражение (unsigned char) 4 > 4 кажется неправильным.

Если вы не можете изменить файлы заголовков сторонних производителей, вы можете попробовать использовать

#undef SWCI_VERSION_MAJOR

но это сильно зависит от #include order