考虑下面的C代码。
#include <stdio.h>
#define foo(x) if (x>0) printf("Ouch\n");
int main()
{
int a = 4;
int b = -3;
if(a>b)
foo(b) ;
else
printf("Arrg!\n");
printf("thanks\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该程序运行时,出现错误提示error: ‘else’ without a previous ‘if’。当我们更换foo(b)与if (b>0) printf("Ouch\n")根据宏定义,不应该将程序转移到下面的代码时,用大括号写的?
if(a>b){
if(x>0){
printf("Ouch\n");
}
}
else{
printf("Arrh!\n");
}
printf("thanks\n");
Run Code Online (Sandbox Code Playgroud)
我不明白为什么编译器会抱怨。该程序实际上转移到了什么?
谢谢
不,这是下面的代码:
if (a > b)
if (b > 0) printf("Ouch\n");;
else
printf("Arrg!\n");
Run Code Online (Sandbox Code Playgroud)
请注意,之后有两个分号("Ouch\n")。这就是破坏代码的原因。在else遵循第二个分号是一个空语句,而不是if之前的语句。原因是您在宏定义中有一个分号,而在宏中又有一个分号。
我建议将类似函数的宏的语句放在其自己的块中,如该答案所示。但这是一般性的建议,在此特定示例中,最好根本没有宏。
问题是您的宏扩展到
if(a>b)
if (b>0) printf("Ouch\n"); ;
else
printf("Arrg!\n");
//...
Run Code Online (Sandbox Code Playgroud)
else因为多余的钱,这不能用;。(也可以在x参数(#define foo(x) if ((x)>0) printf("Ouch\n"))后面加上括号)。
如果您;从宏中丢失了,则将获得不同的解析:else它将与内部匹配,if如下所示:
if(a>b){ /*braces inserted to show the interpretation*/
if (b>0) printf("Ouch\n");
else printf("Arrg!\n");
}
Run Code Online (Sandbox Code Playgroud)
并且当您可以通过悬空使宏解决问题时 else
#define foo(x) if ((x)>0) printf("Ouch\n"); else
//a ; after the macro else would complete the `else` with an empty branch
Run Code Online (Sandbox Code Playgroud)
使用此方法,尤其是在其他方法中使用if- else在诸如gcc/的clang编译器-Wall和类似选项时触发警告,因此最好的处理方法是使用惯用语
#define macro() do{/*macro_body*/}while(0)
Run Code Online (Sandbox Code Playgroud)
就你而言
#define foo(x) do{ if ((x)>0) printf("Ouch\n"); }while(0)
Run Code Online (Sandbox Code Playgroud)
有些人喜欢总是将复合语句(由括起来{ })与if/ else语句一起使用,尽管这也可以解决问题,但我觉得如果您制作了函数式宏供其他人使用,则最好不要在其上施加样式。
| 归档时间: |
|
| 查看次数: |
142 次 |
| 最近记录: |