2016-04-22 4 views
2

Почему этот код выдает ошибку:литья с #if в C

#include <stdio.h> 
#define Rep (int)6 
int main(){ 
    #if Rep==6 
     printf("T"); 
    #else 
     printf("F"); 

    #endif 

return 0; 
} 
  1. Почему отказаться от литья?
  2. Является ли это «препроцессорной ошибкой» или «ошибкой компилятора»?
+0

Вы можете сообщить об ошибке? – nielsbot

+0

Ошибка, которую вы, вероятно, видите, связана с тем, что препроцессор не понимает ни имени типа 'int', ни оператора трансляции. Ошибки или предупреждения, которые вы не видите или просто игнорируете, связаны с тем, что (a) вам не хватает обязательного '#include ', (b) 'void main()' должен быть 'int main (void) 'и (c) вывод должен быть завершен символом новой строки:' printf ("T \ n"); '. Компиляторы не обязаны диагностировать все эти проблемы, но вы определенно должны их исправить. –

+0

@nielsbot Ошибка от Eclipse IDE: «Отсутствующий двоичный оператор перед токеном« 6 »« –

ответ

5

Это ошибка препроцессора. Это происходит потому, что препроцессор не понимает, как отличать переменную. Вы не можете использовать код C с #if, просто простыми числами или макросами, которые расширяются до числа.

Если вы не можете изменить Rep, вы можете обойти это с помощником макроса, который удаляет отливку с самого начала:

#include <stdio.h> 

#define X(x) 
#define Y(x) X x 
#define Rep (int)6 

int main(void) { 
#if Y(Rep) == 6 
    printf("%d\n", Y(Rep)); // prints 6 
#endif 
    return 0; 
} 
+5

Это коварный маленький макрос. –

+0

Просто просто '#define Rep ((int) +6)' будет делать. Но подождите, '' '' 'int', так почему же все вместе. –

+0

@JensGustedt Я не согласен с тем, что это проще, потому что оно отличается от типичного синтаксиса синтаксиса. Это означает, что вы должны изменить константу, чтобы добавить хак. И если вы можете изменить константу, не лучше ли было бы удалить бросок, который не имеет эффекта? –

1

Preprossor макросы, которые сочетают в себе слепки и что по-прежнему должны работать в #if которые легко напишите: вы просто добавили немного + перед номером. В вашем случае

#define Rep ((int)+6) 

препроцессор заменяет идентификаторы, которые он не знает, по 0 так что конечный результат будет таким же значением.

Но также, отливка в вашем Rep макроса сама по себе совершенно бесполезна. 6 - int, во всяком случае. Поэтому лучше избегайте приведения для всех целых типов, у которых есть свои собственные литералы, комбинации U и L, поскольку суффикс должен делать в большинстве случаев.