Login
Оператор goto в языках программирования.
1443 просмотров
Перейти к просмотру всей ветки
in Antwort except 02.02.12 11:01
В ответ на:
Я не знаю общепринятых нотаций в С, но читать такой код с ходу тудно. Особенно, если не представляешь, о чем идет речь. Все имена построены на сокращениях и со стороны ни о чем не говорят. Если по условию встречается goto, то это не прокомментировано. Понятно, что тому, кто это писал, это понятно. Но со стороны не понятно, почему был совершен прыжок из основного кода. Каждый goto блок освобождает определенные ресурсы и вызывает return.
Я не знаю общепринятых нотаций в С, но читать такой код с ходу тудно. Особенно, если не представляешь, о чем идет речь. Все имена построены на сокращениях и со стороны ни о чем не говорят. Если по условию встречается goto, то это не прокомментировано. Понятно, что тому, кто это писал, это понятно. Но со стороны не понятно, почему был совершен прыжок из основного кода. Каждый goto блок освобождает определенные ресурсы и вызывает return.
да не знаю, код нормально читается. обычный драйвер на си, то бишь его инициализация. если хоть один сам в своей жизни написал, то сходу понимаешь, что там делается. по-сути использование goto в том примере - это как уже правильно говорил господин simple - реализация отсутствующих в си эксепшенов. но в отличие от последних, goto позволяет довольно однозначно и стройно построить схему stack unrolling, т.е. когда нужно выполнение несколько зависящих друг от друга операций, а в случае ошибки откатывать операции в обратном порядке. в драйверах такое сплошь и рядом. инициализация оборудования, выделение памяти под структуры, инициализация структур и т.п. если в каком-то месте ошибка - откатывать именно пройденные операции.
do a
if (err) goto err_a
do b
if (err) goto err_b
do c
if (err) goto err_c
...
return
...
undo c
err_c:
undo b
err_b:
undo a
err_a:
return
В ответ на:
Зачем для каждого return нужен goto? Почену return нельзя сразу вызвать с того места, где он нужен?]
Зачем для каждого return нужен goto? Почену return нельзя сразу вызвать с того места, где он нужен?]
драйвер пишут люди. куча разных людей. разработка для ядра, где недочёты более трагично отражаются на стабильности системы, чем разработка в юзерспейсе. использование дебаггера либо очень осложнено, либо невозможно. нужно заранее сделать логичный и читаемый код.
вот представим себе, что в теле функций десяток выходов. в случае, если к коду что-то добавили - то добавивший должен был бы в каждом выходе проставлять подчищение за своей добавкой. один return пропустить и не добавить подчистку не легко, а просто очень легко. а потом ищи на уровне ядра, где память текёт. если же выход из функции в одном месте, то и подчистка в любом случае будет автоматически соблюдена при до/переписывании функций.
в данном же примере сильно фанатично старались оставлять лишь один return. я бы в двух последних местах, где стоит goto end_init, тоже бы поставил return. но это в данном случае непринципиально.
