Звездочка не является символьной константой? - PullRequest
0 голосов
/ 26 ноября 2018

foo.cpp:

#define ID A
#if ID == A
#warning "hello, world"
#endif

Компиляция с g++ -c foo.cpp работает нормально: (g ++ v8.2.0)

foo.cpp:3:2: warning: #warning "hello, world" [-Wcpp]
 #warning "hello, world"
  ^~~~~~~

Теперь, если я заменю #define ID A на #define *, тогда я получаю:

foo.cpp:1:12: error: operator '*' has no left operand
 #define ID *
            ^
foo.cpp:2:5: note: in expansion of macro ‘ID’
 #if ID == A
     ^~

Что такого особенного в *?Почему это не в выражении #if?

Ответы [ 2 ]

0 голосов
/ 26 ноября 2018

В вашем сообщении есть две заметки.Во-первых, это не работает, как вы думаете.Это также выдаст предупреждение

#define ID B
#if ID == A
#warning "hello, world"
#endif

Причина в том, что в контексте #if токены предварительной обработки ID и A воспринимаются как макросы и расширяются.Поскольку A не определено, оно «расширяется» до 0. Так же, как и ID через расширение ID -> B -> 0.Таким образом, условие здесь также верно.

Это также отвечает, почему * вызывает ошибку.Он не может быть расширен в дальнейшем (из-за того, что он не является действительным идентификатором), и поэтому вы получаете сравнение * == 0, что является бессмысленным.

Поскольку ваш заголовок подразумевает, что вы пытаетесь сравнить с символьной константой,способ сделать это - определить ID, чтобы развернуть в последовательность токенов символьной константы.

#define ID 'A'
#if ID == 'A'

Теперь она должна работать, как и ожидалось.Как будет #define ID '*'

0 голосов
/ 26 ноября 2018

#if делает не то, что вы думаете.

В вашем первом примере он пытается оценить 0 == 0, которое является допустимым выражением со значением true.

Во втором примере он пытается вычислить * == 0, что не является допустимым выражением.

...