Почему этот макрос 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)

Лундин отмечает, что это старомодно и не нужно. Я всегда считал, что необходимо избегать диагностики, если макрос расширяется до утверждения вида {...}; - Видимо, я был не прав. Я все еще предпочитаю это как стилистический выбор, все же.

Другие вопросы по тегам