Это личное предпочтение, но я лично не люблю бесконечные циклы или ключевое слово continue
. Я бы сделал что-то вроде:
Packet p = { /* some dummy init that doesn't flag islast() true */};
int ret = 0;
while (ret != TIMEOUT && p.type != ABORT && !islast(&p))
{
int ret = receive(&p, time);
if (ret != TIMEOUT)
{
if (ret != 0)
{
log("corrupted %d", ret);
}
else if (p.type != ABORT)
{
ret = check(&p);
if (ret != 0)
{
log("invalid %d", ret);
respond(&p, INVALID);
}
else
{
ret = execute(&p);
if (ret != 0)
{
log("failure %d", ret);
respond(&p, FAILURE);
}
}
}
}
}
if (ret == TIMEOUT)
{
log("timeout");
}
else if (p.type == ABORT)
{
log("abort");
ret = ABORT;
}
else
{
finalise(&p);
}
return ret;
Моя версия выглядит сложнее, чем ваша, но это потому, что она более точно отражает структуру алгоритма. По моему мнению (и это только мнение), такие ключевые слова, как продолжить и разбить, запутывают структуру и не должны использоваться.
Кроме этого, другое главное преимущество состоит в том, что в моей версии вы можете четко видеть условия, которые вызывают выход из цикла, просто просматривая одно место, то есть условие цикла. Кроме того, условия, которые вызывают цикл, обрабатываются вне цикла - концептуально правильное место. Также есть только одна точка выхода для функции.