[英]Why is this C macro causing syntax error?
This is the first time I'm using macros in C and I'm trying to replace a large section of code that I'd normally place into a function with a macro. 这是我第一次在C中使用宏而我正在尝试替换我通常放入带宏的函数中的大部分代码。 This is a part of an interrupt which will be used quite often and therefore I need to optimize it as much as I can.
这是一个经常使用的中断的一部分,因此我需要尽可能地优化它。 After reading the documentation, I've seen that the compiler doesn't support function inlining and I want to avoid the function call overhead.
阅读完文档后,我发现编译器不支持函数内联,我想避免函数调用开销。
The code itself sends data to a serial-in parallel-out shift register and as far as I can see, there's no shorter way to write the piece of code I need. 代码本身将数据发送到串行输入并行移位寄存器,据我所知,编写我需要的代码片段没有更短的方法。
I'm using C18 compiler version 3.41 and MPLAB X IDE. 我正在使用C18编译器版本3.41和MPLAB X IDE。
So here's the code I'm using in function form: 所以这是我在函数形式中使用的代码:
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;
}
I've turned the function into this macro: 我已将该函数转换为此宏:
#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;\
\
}
So what am I doing wrong? 那么我做错了什么?
Update : I removed the comments and am now getting a syntax error in a different location. 更新 :我删除了评论,现在在不同的位置出现语法错误。
检查\\
tokens后没有空格,有些编译器为此发出编译错误。
Lines are spliced before comments are removed, so the \\
in \\//3 invisible zeroes
does does not continue the line. 在删除注释之前拼接行,因此
\\
in \\//3 invisible zeroes
不会继续该行。
You need either to remove the comment or use a C-style comment ( /* 3 invisible zeroes */
) and place the comment before the \\
that continues the line. 您需要删除注释或使用C风格的注释(
/* 3 invisible zeroes */
)并将注释放在继续该行的\\
之前 。
The problem is with the comments and the way the preprocessor deals with them. 问题在于评论和预处理器处理它们的方式。 Remove the comments and this should work fine.
删除评论,这应该工作正常。 Alternativly use /* Comment */
另外使用/ *评论* /
Three suggestions: 三点建议:
First, make sure that there aren't any trailing spaces after each \\
. 首先,确保每个
\\
后没有任何尾随空格。
Second, drop the
()
from the macro name if it's not meant to take any arguments.
其次,如果它不打算接受任何参数,则从宏名称中删除
edit struck per comments below. ()
。
编辑以下评论。
Finally, wrap the contents of the macro in a do {...} while(0)
(with no trailing semicolon). 最后,将
do {...} while(0)
的内容包装在do {...} while(0)
(没有尾随分号)。 This way, when you write first_one();
这样,当你写
first_one();
in your code, you won't have a spurious semicolon after the closing brace. 在你的代码中,在结束括号后你不会有一个虚假的分号。
In short, 简而言之,
#define do_first \
do { \
LATBbits.LATB0 = 1; \
... \
} while(0)
edit Lundin points out that this is old-fashioned and unnecessary. 编辑伦丁指出,这是老式的,没有必要。 I always believed it was required to avoid a diagnostic if a macro expanded to a statement of the form
{...};
我一直认为,如果宏扩展为
{...};
形式的陈述,则需要避免诊断{...};
-- apparently I was wrong. - 显然我错了。 I still prefer it as a stylistic choice, though.
不过,我仍然喜欢它作为一种风格选择。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.