Подтвердить что ты не робот

Как удалить 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: недопустимое целочисленное константное выражение

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

4b9b3361

Ответ 1

Вы можете заставить это работать с малой препроцессором. Из-за того, как препроцессор применяет макросы, вы можете иногда делать некоторые изменения, используя несколько макроуровней. Boost.Preprocessor использует это поведение. Этот код использует тот факт, что (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, которое я добавил.

Ответ 2

Может быть, использование функции 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);

Ответ 3

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

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

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

Ответ 4

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

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

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

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

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

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

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

#undef SWCI_VERSION_MAJOR

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