J’écris un module qui exporte une interface similaire à send
et recv
.
Étant donné que ces fonctions sont censées renvoyer respectivement le nombre d’octets envoyés et reçus, je ne peux pas gérer correctement les erreurs comme je le ferais normalement (c’est-à-dire utiliser des énumérations et renvoyer des valeurs mnémoniques).
Dans une situation comme celle-ci, dois-je définir errno
de la même manière que la bibliothèque standard? Si tel est le cas, errno
spécificité de thread, existe-t-il un moyen d’écrire particulier ou puis-je simplement lui atsortingbuer une valeur?
Edit: expérimentant, j’ai remarqué que la définition de errno
par affectation fonctionnait. Encore: est-ce sûr et portable pour tout système?
C’est un peu vieux, mais errno – section 3 du manuel dit que vous pouvez l’affecter directement, même s’il s’agit d’une macro, et que ce sera un thread local
Non seulement vous pouvez définir errno
, mais dans de nombreux cas, vous devez définir errno
. Lorsque vous appelez certaines fonctions de bibliothèque, vous ne pouvez détecter une erreur de manière fiable que si vous définissez d’abord errno
avec errno
. Voir strtol
pour un exemple .
A partir de la spécification POSIX de strtol
:
[CX] [Option Start] La fonction strtol () ne modifiera pas le paramètre errno si elle réussit.
Puisque 0, {LONG_MIN} ou {LLONG_MIN}, et {LONG_MAX} ou {LLONG_MAX} sont renvoyés en cas d’erreur et sont également des retours valides en cas de succès, une application souhaitant vérifier les situations d’erreur doit définir errno sur 0, puis appeler strtol () ou strtoll (), puis vérifiez errno. [Option Fin]
En fait, vous pouvez probablement faire une gestion des erreurs “correcte” (comme vous dites) depuis que vous retournez un int
.
Utilisez simplement des valeurs non négatives pour le nombre d’octets lus ou écrits et des valeurs négatives pour les codes d’erreur. Vous n’êtes pas obligé de vous limiter à -1
:
enum myerrors { ERR_NO_MEMORY = -1, ERR_BAD_ARGS = -2, ERR_CPU_EXPLODED = -3, // and so on };
Cependant, définir errno
de la manière souhaitée est valide. La norme indique que errno
développe en une valeur modifiable, ce qui signifie que vous pouvez la définir. De C1x/n1425, 7.5 Errors
:
… et
errno
qui se transforme en une lvalue modifiable de type int, dont la valeur est définie sur un numéro d’erreur positif par plusieurs fonctions de bibliothèque.
Vous pouvez simplement atsortingbuer une valeur à errno
, mais n’oubliez pas qu’il existe d’autres moyens de signaler une erreur qui, selon votre situation, peut être plus appropriée:
int *
(ou size_t *
ou celui que vous size_t *
). Vous pouvez ensuite renvoyer un code d’erreur. Oui, vous pouvez l’affecter et oui, l’affectation sera thread-safe. Voir Est-ce que errno thread-safe?
De: http://support.sas.com/documentation/onlinedoc/sasc/doc700/html/lr1/errno.htm
Les seules valeurs portables pour
errno
sontEDOM
etERANGE
Cela répond donc à votre question sur la portabilité.