Phi*_*lip 20 c coding-style goto
goto
在几个SO讨论中已经对这个声明进行了长时间的讨论(见这个和那个),我当然不想重振那些激烈的辩论.
相反,我想专注于goto
s 的单个用例并讨论它的价值和可能的替代方案.
请考虑以下代码片段,这在(至少我自己的)FSM中很常见:
while (state = next_state()) {
switch (state) {
case foo:
/* handle foo, and finally: */
if (error) goto cleanup;
break;
case bar:
/* handle bar, and finally: */
if (error) goto cleanup;
break;
/* ...other cases... */
}
}
return ok;
cleanup:
/* do some cleanup, i.e. free() local heap requests, adjust global state, and then: */
return error;
Run Code Online (Sandbox Code Playgroud)
在一个单独的函数中交换清理东西只是为了保存goto
s似乎很尴尬.另一方面,我们已经被提出来谴责goto
尽可能使用s.
我的问题:我的代码示例被认为是好风格吗?
如果没有,是否有可行的替代方案?
请坚持上述具体用法goto
.我不想深入研究关于一般用途的另一个讨论goto
.
pmg*_*pmg 11
你的用法goto
还可以.它没有打破使用goto的两种好方法.
goto
必须在源头中下载(几行)goto labels
必须包含goto
语句我不会将清理逻辑提取到自己的函数中并从不同的地方调用它,而是考虑将switch语句提取到一个单独的函数中并从中返回错误代码.在while循环中,您可以检查返回代码并进行清理并在必要时返回.
如果你有开关和清理逻辑之间共享了很多资源,那么我想转到将preferrable周围路过这一切的状态.
你有时不需要转到switch
.使用两者switch
并goto
只是增加了复杂性.
while (state) {
switch (state) {
case cleanup:
/* do some cleanup, i.e. free() local heap requests, adjust global state, and then: */
return error;
case foo:
/* handle foo, and finally: */
if (error) { state = cleanup; continue; }
break;
case bar:
/* handle bar, and finally: */
if (error) { state = cleanup; continue; }
break;
/* ...other cases... */
}
state = next_state();
}
return ok;
Run Code Online (Sandbox Code Playgroud)