Pourquoi retourner un errno négatif? (par exemple, retour -EIO)

Un autre exemple simple:

if (wpa_s->mlme.ssid_len == 0) return -EINVAL; 

Pourquoi le moins unaire? Est-ce (généralement) fait pour les fonctions qui retournent> 0 en cas de succès et <(=) 0 en cas d'échec, ou existe-t-il une autre raison?

C’est essentiellement les raisons. Beaucoup de fonctions ont beaucoup de “bons” résultats positifs, ce qui laisse les valeurs négatives pour les codes d’erreur.

Les codes d’erreur C / POSIX sont un peu “historiquement développés”, il est donc peu logique d’essayer de leur atsortingbuer trop de rimes ou de raisons.

Beaucoup plus de langues modernes lèvent des exceptions pour les erreurs afin de ne pas avoir à détourner une partie de leur plage de réponse possible pour les codes d’erreur. Bien sûr, il y a des compromis dans les deux sens.

Tout d’abord, ce n’est pas vraiment un truc en C. Vous regardez une fonction qui est écrite en C pour une raison quelconque. Les mêmes conventions peuvent être utilisées dans toutes les langues.

À l’époque de mon ancienne époque Unix, il existait en quelque sorte une convention selon laquelle 0 signifiait succès, un chiffre positif signifiait des problèmes mineurs et un nombre négatif signifiant une sorte d’échec. Par conséquent, il y avait aussi une sorte de convention de if (foo() >= 0) { /* success of a sort */ } .

Cela était sans doute lié aux codes de retour de processus Unix, où 0 était un succès.

Votre compréhension est globalement correcte. L’interprétation évidente est la bonne.

La convention standard diffère toutefois légèrement de votre formule.

Sous Unix, un programme qui se termine avec le statut 0 vérifie si les utilitaires de niveau CLI tels que le shell sont vérifiés. Dans la bibliothèque, -1 est généralement un retour d’erreur.

Cela conduit à un paradigme général où >= 0 signifie bon et < 0 signifie erreur. Rien de tout cela n'est gravé dans la pierre.

BTW, cela pourrait être classé comme le modèle sentinelle et vous pourriez l'appeler un retour sentinelle. C'est en fait une combinaison d'une "valeur" sentinelle et d'un code d'erreur. Il est plus facile de taper et de sécuriser les threads que de renvoyer un code d'erreur à un endroit et une valeur de sentinelle pour une erreur à un autre.

Wikipedia signale qu'une valeur sentinelle est utilisée pour terminer une boucle, mais je pense qu'un retour de fonction serait un cas beaucoup plus courant. Personne n'est précisément responsable de ces définitions.

Du sharepoint vue de l’optimisation, l’utilisation de nombres négatifs permet aux kernelx basés sur Unix de rechercher un code d’erreur en utilisant une seule comparaison au lieu de deux.

Les fonctions du kernel renvoient souvent des codes d’erreur à la place des pointeurs. Cela signifie que les codes d’erreur ne peuvent pas chevaucher des adresses de pointeurs valides. Ils doivent donc être les valeurs non signées les plus basses (>= 0) ou les plus élevées (<= unsigned max) .

La vérification des valeurs de pointeur pour NULL et pour les codes d'erreur étant des opérations extrêmement courantes, il est donc logique de les optimiser.

En général, les valeurs inférieures < 0x8000 sont NULL et les principales sont des codes d'erreur (rappelez-vous que -1 est stocké sous la forme 0xff...ff , la valeur maximale non signée possible).

Cela signifie que vous pouvez utiliser une comparaison pour vérifier chacune:

NULL si x <= 0x8000 (vrai pour 0 à 0x8000)

ERRNO si x >= (unsigned long)(-MAX_ERRNO) (vrai pour -1 à -MAX_ERRNO)

Vous pouvez voir cela se produire dans le fichier err.h de Linux.