Есть ли способ, чтобы препроцессор C разрешил макросы в операторе #error? - PullRequest
11 голосов
/ 14 мая 2011

Так же, как говорится в названии. Я хочу использовать макрос препроцессора в тексте оператора #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 C ++ для этого, потому что на самом деле директива препроцессора #error не указана ни в одном стандарте ISO C ++. Однако я знаю, что GCC и Visual C ++ поддерживают #error. Но мой вопрос не относится к этим компиляторам, мне просто любопытно, может ли это сделать какой-либо компилятор / препроцессор C / C ++.

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

Ответы [ 3 ]

5 голосов
/ 14 мая 2011

Для полноты C ++ 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]"
5 голосов
/ 14 мая 2011

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

#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 голосов
/ 15 мая 2011
#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

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

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

...