Есть ли способ разрешить макросы C Preprocessor в операторе #error?

Как гласит название. Я хочу использовать макрос препроцессора в тексте оператора #error:

#define SOME_MACRO 1

#if SOME_MACRO != 0
    #error "SOME_MACRO was not 0; it was [value of SOME_MACRO]"
#endif

В этом примере я хочу, чтобы препроцессор разрешил [value of SOME_MACRO] фактическое значение SOME_MACRO, которое в этом случае равно 1. Это должно произойти до того, как препроцессор, компилятор или любые другие процессы #error распечатывают вывод ошибки
Есть ли способ сделать это или это просто невозможно?

Я не хочу знать, есть ли стандартный способ ISO С++, потому что afaik директива препроцессора #error не указана ни в одном стандарте ISO С++. Однако я знаю поддержку GCC и Visual С++ #error. Но мой вопрос не является специфическим для этих компиляторов, мне просто интересно, может ли это сделать компилятор/препроцессор C/С++.

Я попытался найти эту тему, но не повезло.

Ответ 1

Для полноты С++ 0x я предложил (используя тот же трюк, что и Кирилл):

#define STRING2(x) #x
#define STRING(x) STRING2(x)

#define EXPECT(v,a) static_assert((v)==(a), "Expecting " #v "==" STRING(a) " [" #v ": "  STRING(v) "]")


#define VALUE 1

EXPECT(VALUE, 0);

дает:

g++ -Wall -Wextra -std=c++0x test.cc                     
test.cc:9: error: static assertion failed: "Expecting VALUE==0 [VALUE: 1]"

Ответ 2

В Visual Studio вы можете использовать pragma message следующим образом:

#define STRING2(x) #x
#define STRING(x) STRING2(x)

#define SOME_MACRO 1

#if SOME_MACRO != 0
    #pragma message ( "SOME_MACRO was not 0; it was " STRING(SOME_MACRO) )
    #error SOME_MACRO was not 0;
#endif

Это приведет к генерации двух сообщений, но вы получите значение SOME_MACRO. В g++ используйте вместо этого (из комментариев: g++ версия 4.3.4 хорошо работает с круглыми скобками, как в приведенном выше коде):

#pragma message "SOME_MACRO was not 0; it was " STRING(SOME_MACRO)

Ответ 3

#define INVALID_MACRO_VALUE2(x) <invalid_macro_value_##x>
#define INVALID_MACRO_VALUE(x) INVALID_MACRO_VALUE2(x)

#if SOME_MACRO != 0
  #include INVALID_MACRO_VALUE(SOME_MACRO)
#endif

создает "Невозможно открыть файл include:" invalid_macro_value_1 ": нет такого файла или каталога" в Visual Studio 2005 и, возможно, подобные сообщения для других компиляторов.

Это не отвечает на ваш вопрос напрямую об использовании #error, но результат схож.