Каков наилучший способ управления ресурсами для программы C .Должен ли я использовать вложенную структуру if или использовать операторы goto?
Я знаю, что существует много табу о goto утверждениях.Тем не менее, я думаю, что это оправдано для очистки местного ресурса.Я предоставил два образца.Один сравнивает вложенную структуру if, а другой использует операторы goto.Лично я нахожу, что операторы goto облегчают чтение кода.Для тех, кто может утверждать, что вложено, если предлагает лучшую структуру, представьте, что тип данных был чем-то отличным от char *, например дескриптор Windows.Я чувствую, что вложенная структура , если выйдет из-под контроля с рядом функций CreateFile или любой другой функцией, которая принимает большое количество параметров.
Эта статья демонстрирует, что локальные операторы goto создают RAII для кода C.Код аккуратный, легко следовать.Представьте, что это серия из вложенных, если операторов.
Я понимаю, что goto является табу во многих других языках, потому что существуют другие механизмы управления, такие как try / catch и т. Д., Однако, в C это представляется целесообразным.
#include <stdlib.h>
#define STRING_MAX 10
void gotoExample()
{
char *string1, *string2, *string3, *string4, *string5;
if ( !(string1 = (char*) calloc(STRING_MAX, sizeof(char))) )
goto gotoExample_string1;
if ( !(string2 = (char*) calloc(STRING_MAX, sizeof(char))) )
goto gotoExample_string2;
if ( !(string3 = (char*) calloc(STRING_MAX, sizeof(char))) )
goto gotoExample_string3;
if ( !(string4 = (char*) calloc(STRING_MAX, sizeof(char))) )
goto gotoExample_string4;
if ( !(string5 = (char*) calloc(STRING_MAX, sizeof(char))) )
goto gotoExample_string5;
//important code goes here
gotoExample_string5:
free(string4);
gotoExample_string4:
free(string3);
gotoExample_string3:
free(string2);
gotoExample_string2:
free(string1);
gotoExample_string1:
}
void nestedIfExample()
{
char *string1, *string2, *string3, *string4, *string5;
if (string1 = (char*) calloc(STRING_MAX, sizeof(char)))
{
if (string2 = (char*) calloc(STRING_MAX, sizeof(char)))
{
if (string3 = (char*) calloc(STRING_MAX, sizeof(char)))
{
if (string4 = (char*) calloc(STRING_MAX, sizeof(char)))
{
if (string5 = (char*) calloc(STRING_MAX, sizeof(char)))
{
//important code here
free(string5);
}
free(string4);
}
free(string3);
}
free(string2);
}
free(string1);
}
}
int main(int argc, char* argv[])
{
nestedIfExample();
gotoExample();
return 0;
}
Я также хотел бы процитировать Линуса Торвальдса о goto инструкциях внутри Linux Kernel .
И иногда структура плохая ,и встает на пути, и использование «goto» просто намного понятнее.
Например, довольно часто встречаются условные выражения, которые НЕ ГНЕЗДАЮТСЯ.
В этом случае у вас есть двавозможности
используйте goto и будьте счастливы, так как это не требует вложенности
Это делает код более читабельным, поскольку код простовыполняет то, что говорит алгоритм:
продублируйте код и перепишите его во вложенной форме, чтобы вы могли
использовать структурированные переходы.
Это часто делает код намного МЕНЬШЕ читаемым, сложнее в обслуживании и больше.
Язык Паскаль является ярким примером последней проблемы.Поскольку в нем нет оператора «break», циклы в (традиционном) Pascal часто выглядят как полное дерьмо, потому что вы должны добавить совершенно произвольную логику, чтобы сказать «Я закончил сейчас».
Приемлемо ли goto для управления ресурсами?Должен ли я использовать вложенных, если операторов или есть лучший способ?
Обновление: Примеры хороших Gotos In C