Résumé :
Une fonction en C doit-elle toujours vérifier pour ne pas déréférencer un NULL
pointeur? Sinon, quand est-il approprié de sauter ces vérifications?
Détails :
J'ai lu des livres sur la programmation des interviews et je me demande quel est le degré approprié de validation d'entrée pour les arguments de fonction en C? De toute évidence, toute fonction qui prend la saisie d'un utilisateur doit effectuer la validation, y compris la vérification d'un NULL
pointeur avant de le déréférencer. Mais qu'en est-il dans le cas d'une fonction dans le même fichier que vous ne vous attendez pas à exposer via votre API?
Par exemple, ce qui suit apparaît dans le code source de 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;
}
Si *graph
est NULL
alors un pointeur nul sera déréférencé, plantant probablement le programme, mais pouvant entraîner un autre comportement imprévisible. D'un autre côté, la fonction est static
et donc peut-être que le programmeur a déjà validé l'entrée. Je ne sais pas, je viens de le sélectionner au hasard car c'était un court exemple dans un programme d'application écrit en C. J'ai vu beaucoup d'autres endroits où des pointeurs sont utilisés sans vérifier NULL. Ma question n'est généralement pas spécifique à ce segment de code.
J'ai vu une question similaire posée dans le contexte de la remise d'exceptions . Cependant, pour un langage dangereux tel que C ou C ++, il n'y a pas de propagation d'erreur automatique des exceptions non gérées.
D'un autre côté, j'ai vu beaucoup de code dans des projets open source (comme l'exemple ci-dessus) qui ne vérifie pas les pointeurs avant de les utiliser. Je me demande si quelqu'un a des réflexions sur les directives pour savoir quand mettre des vérifications dans une fonction par rapport à l'hypothèse que la fonction a été appelée avec des arguments corrects.
Je m'intéresse à cette question en général pour écrire du code de production. Mais je m'intéresse également au contexte des interviews de programmation. Par exemple, de nombreux manuels d'algorithmes (tels que CLR) ont tendance à présenter les algorithmes en pseudocode sans vérification d'erreur. Cependant, bien que cela soit bon pour comprendre le cœur d'un algorithme, ce n'est évidemment pas une bonne pratique de programmation. Je ne voudrais donc pas dire à un intervieweur que je sautais la vérification des erreurs pour simplifier mes exemples de code (comme le pourrait un manuel). Mais je ne voudrais pas non plus sembler produire un code inefficace avec une vérification d'erreur excessive. Par exemple, le graph_get_current_column_color
pourrait avoir été modifié pour vérifier *graph
null, mais ce n'est pas clair ce qu'il ferait s'il *graph
était nul, sinon il ne devrait pas le déréférencer.