为什么这个C宏会导致语法错误?

时间:2012-05-05 16:37:49

标签: c macros embedded pic c18

这是我第一次在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 个答案:

答案 0 :(得分:8)

检查\令牌后面没有空格,有些编译器为此发出编译错误。

答案 1 :(得分:3)

在删除评论之前拼接行,因此\中的\//3 invisible zeroes 不会延续该行。

您需要删除评论或使用C风格的评论(/* 3 invisible zeroes */),然后将评论放在继续该行的\之前。

答案 2 :(得分:1)

问题在于评论和预处理器处理它们的方式。删除评论,这应该工作正常。 另外使用/ *评论* /

答案 3 :(得分:1)

三点建议:

首先,确保每个\后没有任何尾随空格。

其次,如果不打算采用任何参数,请从宏名称中删除() 编辑按照以下评论进行操作。

最后,将宏的内容包装在do {...} while(0)中(没有尾随分号)。这样,当你在代码中编写first_one();时,在结束括号后你将不会有一个虚假的分号。

简而言之,

#define do_first         \
  do {                   \
    LATBbits.LATB0 = 1;  \
    ...                  \
  } while(0)

编辑 Lundin指出这是老式的,没有必要。我一直认为,如果宏扩展为{...};形式的陈述,则需要避免诊断 - 显然我错了。不过,我仍然喜欢它作为一种风格选择。