Где-то так. Если ради "избавления от goto" надо писать
if(!cond1) {
stmt1;
if(!cond2) {
stmt2;
if(!cond3) {
stmt3;
if(!cond4) {
stmt4;
}
}
}
}
То не стесняйся писать
if(cond1) goto end;
stmt1;
if(cond2) goto end;
stmt2;
if(cond3) goto end;
stmt3;
if(cond4) goto end;
stmt4;
end: ;
ну либо выделять это в функцию и вместо goto писать много return (что с одной стороны тоже ругается пуристами, а с другой - не всегда удобно).
Кстати, я, бывает, и такое заворачиваю:
status_t func() {
status_t status;
(void) ( ok != (status = func1())
|| ok != (status = func2())
|| ok != (status = func3())
|| ok != (status = func4())
);
return status;
}
вместо
status_t func() {
status_t status;
status = func1();
if( status != ok) return status;
status = func2();
if( status != ok) return status;
status = func3();
if( status != ok) return status;
return func4();
}
и тем более "пуристического" варианта
status_t func() {
status_t status;
status = func1();
if( status == ok) {
status = func2();
if( status == ok) {
status = func3();
if( status == ok)
status = func4();
}
}
return status;
}