之前在博文中说过do while(0)的用法, 不过实际项目中用得不多。 最近遇到麻烦了, 感觉到不用do while(0)就很蛋疼。
先来看一段比较常规的丑代码:
#include<iostream>
using namespace std;
int fun(int a, int b, int c, int d)
{
int errCode = 0;
if(a < 0)
{
errCode = -1;
printf("error1\n");
printf("code xxx, err code is %d\n", errCode);
printf("code yyy, err code is %d\n", errCode);
printf("code zzz, err code is %d\n", errCode);
return errCode;
}
int r1 = 0;
if(b < 0)
{
errCode = -2;
printf("error2\n");
printf("code xxx, err code is %d\n", errCode);
printf("code yyy, err code is %d\n", errCode);
printf("code zzz, err code is %d\n", errCode);
return errCode;
}
int r2 = 0;
if(c < 0)
{
errCode = -3;
printf("error3\n");
printf("code xxx, err code is %d\n", errCode);
printf("code yyy, err code is %d\n", errCode);
printf("code zzz, err code is %d\n", errCode);
return errCode;
}
int r3 = 0;
if(d < 0)
{
errCode = -4;
printf("error4\n");
printf("code xxx, err code is %d\n", errCode);
printf("code yyy, err code is %d\n", errCode);
printf("code zzz, err code is %d\n", errCode);
return errCode;
}
int r4 = 0;
// add normal business logic here
printf("code xxx, err code is %d\n", errCode);
printf("code yyy, err code is %d\n", errCode);
printf("code zzz, err code is %d\n", errCode);
return errCode;
}
int main()
{
fun(-1, -1, -1, -1);
return 0;
}
我们可以看到, 代码存在极大的冗余, 一坨一坨的, 像什么样! 于是, 有的人说用goto可以搞定啊。 且不说goto为人诟病已久, 先来看看goto的效果:
#include<iostream>
using namespace std;
int fun(int a, int b, int c, int d)
{
int errCode = 0;
if(a < 0)
{
errCode = -1;
printf("error1\n");
goto END;
}
int r1 = 0;
if(b < 0)
{
errCode = -2;
printf("error2\n");
goto END;
}
int r2 = 0;
if(c < 0)
{
errCode = -3;
printf("error3\n");
goto END;
}
int r3 = 0;
if(d < 0)
{
errCode = -4;
printf("error4\n");
goto END;
}
int r4 = 0;
// add normal business logic here
END:
printf("code xxx, err code is %d\n", errCode);
printf("code yyy, err code is %d\n", errCode);
printf("code zzz, err code is %d\n", errCode);
return errCode;
}
int main()
{
fun(-1, -1, -1, -1);
return 0;
}
经验比较丰富的同学一眼就可以看出问题, 这里存在编译问题。 在linux GCC下提示:crosses initialization of xxx, 在Windows VC++下提示:initialization of 'r4' is skipped by 'goto END'
那怎么办呢? 也不是完全么有办法, 方法1是把所有被跳过的变量放在最前面定义, 方法2是直接用大括号把被掉过的变量括起来。 在实际中, 这两种方法我都玩过。 第一种方法非常繁琐(当时搞一个安全问题, 写代码的时候用了这个方式), 要重新移动变量的位置, 而第二种方法显得很猥琐(当时是搞一个节日活动的问题, 写代码的时候用了这种方式), 谁用谁知道。
还是来看看do while(0)的实现方式吧, 我最近就是这么搞的, 相对较爽:
#include<iostream>
using namespace std;
int fun(int a, int b, int c, int d)
{
int errCode = 0;
do
{
if(a < 0)
{
errCode = -1;
printf("error1\n");
break;
}
int r1 = 0;
if(b < 0)
{
errCode = -2;
printf("error2\n");
break;
}
int r2 = 0;
if(c < 0)
{
errCode = -3;
printf("error3\n");
break;
}
int r3 = 0;
if(d < 0)
{
errCode = -4;
printf("error4\n");
break;
}
int r4 = 0;
}while(0);
// add normal business logic here
printf("code xxx, err code is %d\n", errCode);
printf("code yyy, err code is %d\n", errCode);
printf("code zzz, err code is %d\n", errCode);
return errCode;
}
int main()
{
fun(-1, -1, -1, -1);
return 0;
}
搞定!