Почему этот макрос C вызывает синтаксическую ошибку?
Это первый раз, когда я использую макросы в C и пытаюсь заменить большой фрагмент кода, который я обычно помещаю в функцию, макросом. Это часть прерывания, которое будет использоваться довольно часто, и поэтому мне нужно максимально оптимизировать его. После прочтения документации я увидел, что компилятор не поддерживает встраивание функций, и я хочу избежать накладных расходов на вызовы функций.
Сам код отправляет данные в сдвиговый регистр с последовательным параллельным выходом, и, насколько я вижу, нет более короткого способа написать фрагмент кода, который мне нужен.
Я использую компилятор C18 версии 3.41 и MPLAB X IDE.
Итак, вот код, который я использую в форме функции:
void first_one(void)
{
//3 invisible zeroes
LATBbits.LATB1=0; //data set to zero
LATBbits.LATB0=1;//first clock
LATBbits.LATB0=0;
LATBbits.LATB0=1;//second clock
LATBbits.LATB0=0;
LATBbits.LATB0=1;//third clock
LATBbits.LATB0=0;
//end of invisible zeroes
//two visible zeroes
LATBbits.LATB0=1;//first clock
LATBbits.LATB0=0;
LATBbits.LATB0=1;//second clock
LATBbits.LATB0=0;
//end of two visible zeroes
LATBbits.LATB1=1;//Data is now one
LATBbits.LATB0=1;
LATBbits.LATB0=0;
//one
LATBbits.LATB1=0;//Data is now zero
LATBbits.LATB0=1;//first clock
LATBbits.LATB0=0;
LATBbits.LATB0=1;//second clock
LATBbits.LATB0=0;
//after this, everything should be in place
LATBbits.LATB0=1;
LATBbits.LATB0=0;
}
Я превратил функцию в этот макрос:
#define first_one() { \
\
LATBbits.LATB1=0;\
\
LATBbits.LATB0=1;\
LATBbits.LATB0=0;\
\
LATBbits.LATB0=1;\
LATBbits.LATB0=0;\
\
LATBbits.LATB0=1;\
LATBbits.LATB0=0;\
\
LATBbits.LATB0=1;\
LATBbits.LATB0=0;\
\
LATBbits.LATB0=1;\
LATBbits.LATB0=0;\
\
LATBbits.LATB1=1;\
\
LATBbits.LATB0=1;\
LATBbits.LATB0=0;\
\
LATBbits.LATB1=0;\
^^^ The syntax error is here!
\
LATBbits.LATB0=1;\
LATBbits.LATB0=0;\
\
LATBbits.LATB0=1;\
LATBbits.LATB0=0;\
\
LATBbits.LATB0=1;\
LATBbits.LATB0=0;\
\
}
Так что я делаю не так?
Обновление: я удалил комментарии и теперь получаю синтаксическую ошибку в другом месте.
4 ответа
Проверьте, нет ли пробелов после \
токены, некоторые компиляторы выдают ошибку компиляции для этого.
Линии сращиваются до удаления комментариев, поэтому \
в \//3 invisible zeroes
не продолжает линию.
Вам нужно либо удалить комментарий, либо использовать комментарий в стиле C (/* 3 invisible zeroes */
) и разместите комментарий перед \
это продолжает линию.
Проблема в комментариях и в том, как их обрабатывает препроцессор. Удалите комментарии, и это должно работать нормально. Альтернативно используйте /* Комментарий */
Три предложения:
Во-первых, убедитесь, что после каждого \
,
Во-вторых, бросьте ()
из имени макроса, если он не предназначен для каких-либо аргументов. править по комментариям ниже.
Наконец, оберните содержимое макроса в do {...} while(0)
(без запятой). Таким образом, когда вы пишетеfirst_one();
в вашем коде у вас не будет ложной точки с запятой после закрывающей скобки.
Короче,
#define do_first \
do { \
LATBbits.LATB0 = 1; \
... \
} while(0)
Лундин отмечает, что это старомодно и не нужно. Я всегда считал, что необходимо избегать диагностики, если макрос расширяется до утверждения вида {...};
- Видимо, я был не прав. Я все еще предпочитаю это как стилистический выбор, все же.