让我解释一下我对示例代码的困惑
这是我们的宏
#define rsAssert(v) if(!(v)) printf("rsAssert failed: %s, in %s at %i" #v, __FILE__, __LINE__);
案例1:
int main(void)
{
rsAssert(0);
return 0;
}
此案例成功编译
案例2
int main(void)
{
rsAssert(0) // note here ; is not present
return 0;
}
这也是无懈可击的 问题1:
这意味着您是在写rsAssert(0)
还是rsAssert(0);
之间没有区别?
然后
案例3
int main()
{
if(1)
rsAssert(0);
else
printf("mr.32");
return 0;
}
这里rsassert(0);
不会编译[见http://ideone.com/7dFv1] 但没有;
rsasser(0)
正常[见http://ideone.com/8fehl] ..
我不知道宏观扩张在这里发生了什么......
答案 0 :(得分:4)
它在案例3中不起作用的原因是因为这是实际编译的内容:
int main()
{
if(1)
if(!(v)) printf("rsAssert failed: %s, in %s at %i", #v, __FILE__, __LINE__);;
else
printf("mr.32");
return 0;
}
请注意宏中第一个printf末尾的额外分号。
通常情况下,使用if语句,后跟单个语句或带有{}的块。
但由于额外的,你有这个:
if (...)
printf(...); ;
else
printf(...);
return 0;
这个额外的分号是一个空洞的陈述,但仍然是一个陈述。
你应该删除;从宏观。然后事情会更有意义。
答案 1 :(得分:4)
这是我总是强制我的程序员在所有if语句中使用主体的最大原因。
int main()
{
if (1)
if(!(0))
printf("rsAssert failed: %s, in %s at %i", "0", __FILE__, __LINE__);
else
printf("mr.32");
return 0;
}
受到良好编码标准的阻碍
int main()
{
if (1){
if(!(0)){
printf("rsAssert failed: %s, in %s at %i", "0", __FILE__, __LINE__);
}
}
else {
printf("mr.32");
}
return 0;
}
修复了低成本的变化列表。
#define rsAssert(v) (printf( (!v)?"rsAssert failed: %s, in %s at %i":"", #v, __FILE__, __LINE__))
这将有效但总是会打印一个printf。
#define rsAssert(v) ((!v)?printf("rsAssert failed: %s, in %s at %i", #v, __FILE__, __LINE__):0)
这只会在你查询断言时打印出来,但看起来很麻烦
还要考虑以下几点!
if( rand()%2 )
FooLog("Hello World");
ImportantFunction();
#if DEBUG
#define FooLog printf
#else
#define FooLog //
#endif
在发布时,重要功能在50%的时间内100%有效。
答案 2 :(得分:2)
我预计在案例3中根本不起作用。手工扩张(并使其有意义):
int main()
{
if (1)
if(!(0))
printf("rsAssert failed: %s, in %s at %i", "0", __FILE__, __LINE__);
else
printf("mr.32");
return 0;
}
正如您所看到的,else
最终会出现错误的if
声明。如果您希望包含if
语句的宏起作用,则需要使其看起来像一个简单的语句。将其包含在do... while(0)
中是惯用的:
#define rsAssert(v) \
do { \
if(!(v)) \
printf("rsAssert failed: %s, in %s at %i", #v, __FILE__, __LINE__); \
} while (0)
答案 3 :(得分:1)
if(1)
rsAssert(0); // Original semicolon
else
....
扩展为
if(1)
if(!(v)) printf("rsAssert failed: %s, in %s at %i",
#v, __FILE__, __LINE__);; // Notice the extra semicolon. The extra from the
// macro expansion.
else
....
这个额外的分号会导致一个新的空语句。由于没有{}
,因此对于if语句,else
不会立即被跟踪,而且编译器正在抱怨。所以,做 -
if(1)
{
rsAssert(0);
}
else
....