Почему #define INVALID_VALUE -999;дать синтаксическую ошибку при использовании? - PullRequest
3 голосов
/ 27 декабря 2010

Я пытаюсь сравнить с определенными константами в C, и я упростил мою программу до следующего:

#include "stdio.h"
#include "stdlib.h"
#define INVALID_VALUE -999;

int main(void)
{
    int test=0;
    if(test==INVALID_VALUE) //The error line..
        return INVALID_VALUE;
    return 0;
}

И когда я использую gcc для компиляции, выдается ошибка "error: expected ‘)’ before ‘;’ token".

Есть ли причина, по которой это невозможно сделать?

Ответы [ 6 ]

11 голосов
/ 27 декабря 2010

Удалите точку с запятой из определения INVALID_VALUE.

Макросы заменяются лексически (посимвольно) без понимания синтаксиса вокруг них.Ваш макрос INVALID_VALUE установлен на -999;, поэтому ваша строка if расширяет макрос до:

if (test==-999;)

, что является недопустимым синтаксисом языка Си.

6 голосов
/ 27 декабря 2010

Вам необходимо удалить ; в #define INVALID_VALUE -999;.См. фиксированный код .

. Вы могли бы прийти к такому выводу, поняв, что сообщало вам сообщение об ошибке expected ‘)’ before ‘;’ token.Он говорит вам, что ожидал найти ) перед ; токеном, но при проверке одной линии вы не увидите ;.Так, может быть, есть один в определении INVALID_VALUE?Посмотрите на #define INVALID_VALUE -999; и вот оно!Думаешь, это должно быть там, но не уверен?Итак, давайте попробуем удалить его и посмотреть, работает ли он.Успех!

Эта страница содержит объяснение, почему не следует заключать #define с точкой с запятой, даже если это необходимо при использовании макроса.Хорошо учиться как можно больше на своей ошибке, чтобы ты не повторил ее снова.Цитата:

Определения макросов, независимо от того, расширяются они до одного или нескольких операторов, не должны заканчиваться точкой с запятой.Если требуется, точка с запятой должна быть включена после расширения макроса.Случайная вставка точки с запятой в конце определения макроса может неожиданно изменить поток управления программой.

Еще один способ избежать этой проблемы - предпочесть встроенные или статические функции функциональным макросам.

В общем, программист должен убедиться, что в конце определения макроса нет точки с запятой.Ответственность за использование точки с запятой при использовании такого макроса должна быть делегирована лицу, вызывающему макрос.

3 голосов
/ 27 декабря 2010

Язык макросов препроцессора C отличается от C


; в определении макроса следует удалить.

Это понятная ошибка. Если бы C был разработан сегодня, макроязык мог бы быть более интегрированным с остальной частью C.

Но на 16-битных машинах в начале 1970-х годов, когда был изобретен C, было неразумно писать слишком сложную программу. Это закончится бесполезно, так как на самом деле не останется памяти, чтобы на самом деле запустить программу большого шедевра, и даже простые программы работали медленно.

Таким образом, C был разбит на довольно простой макрос-препроцессор, который изначально был совершенно отдельной программой и собственно компилятором. Программа препроцессора не пыталась выполнить синтаксический анализ языка C, кроме понимания модели лексического анализа.

Когда 32-битные машины вступили во владение, препроцессор обычно был интегрирован в синтаксический анализатор, но, естественно, язык должен был оставаться прежним.

2 голосов
/ 27 декабря 2010

Изменить макрос

от

#define INVALID_VALUE -999;

до

#define INVALID_VALUE -999

Bye

2 голосов
/ 27 декабря 2010

Вам не нужно ставить точку с запятой после определения чего-либо. #define на самом деле является макросом, и он выполняет встроенное расширение при компиляции.

Таким образом,

#define IDENTIFIER 10;
int j = IDENTIFIER;

будет расширяться как:

int j = 10;;
2 голосов
/ 27 декабря 2010

Точка с запятой в конце

#define INVALID_VALUE -999;

Классический.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...