Резюме :
Должна ли функция в C всегда проверять, чтобы не разыменовывать NULL
указатель? Если нет, то когда уместно пропустить эти проверки?
Детали :
Я читал несколько книг о программировании интервью, и мне интересно, какова соответствующая степень проверки ввода для аргументов функции в C? Очевидно, что любая функция, которая принимает входные данные от пользователя, должна выполнить проверку, включая проверку NULL
указателя перед разыменованием его. Но как насчет функции в том же файле, которую вы не ожидаете представить через свой API?
Например , в исходном коде git появляется следующее :
static unsigned short graph_get_current_column_color(const struct git_graph *graph)
{
if (!want_color(graph->revs->diffopt.use_color))
return column_colors_max;
return graph->default_column_color;
}
Если *graph
is, NULL
то нулевой указатель будет разыменован, возможно, приведет к сбою программы, но, возможно, приведет к некоторому другому непредсказуемому поведению. С другой стороны, эта функция static
и, возможно, программист уже подтвердил ввод. Я не знаю, я просто выбрал его случайным образом, потому что это был короткий пример в прикладной программе, написанной на C. Я видел много других мест, где указатели используются без проверки на NULL. Мой вопрос вообще не специфичен для этого сегмента кода.
Я видел аналогичный вопрос, заданный в контексте передачи исключений . Однако для небезопасных языков, таких как C или C ++, не существует автоматического распространения ошибок необработанных исключений.
С другой стороны, я видел много кода в проектах с открытым исходным кодом (например, в примере выше), который не делает никаких проверок указателей перед их использованием. Мне интересно, есть ли у кого-нибудь мысли о рекомендациях относительно того, когда ставить проверки в функции, а не о том, что функция вызывается с правильными аргументами.
Меня вообще интересует этот вопрос для написания производственного кода. Но я также заинтересован в контексте программных интервью. Например, многие учебники по алгоритмам (такие как CLR) стремятся представить алгоритмы в псевдокоде без какой-либо проверки ошибок. Однако, хотя это хорошо для понимания сути алгоритма, это явно не хорошая практика программирования. Поэтому я не хотел бы говорить интервьюеру, что я пропускаю проверку ошибок, чтобы упростить мои примеры кода (как это может сделать учебник). Но я также не хотел бы создавать неэффективный код с чрезмерной проверкой ошибок. Например, объект graph_get_current_column_color
мог быть изменен для проверки *graph
на нулевое значение, но не ясно, что он будет делать, если *graph
будет нулевым, кроме того, что он не должен разыменовывать его.