Tout avantage à utiliser les WEXITSTATUS macro en C au cours de la division par 256 sur exit() de statut?
Je faisais un exercice à l'université, où j'ai dû renvoyer une valeur à la sortie, cette valeur était en fait un compte de quelque chose. Cela pourrait être au-dessus de 255 (exit() ne peut pas gérer), mais le professeur a proposé d'utiliser des données de test où le comte ne pourrait jamais aller au-dessus de cette valeur.
Après tout cela, j'avais besoin de gérer cette valeur de nombre, le statut de sortie, j'ai eu cette valeur dans les principaux processus à l'aide de waitpid(). À ma grande surprise, si le processus de l'enfant est retourné 1, la valeur "réelle" dans le processus principal était de 256, 2 était de 512 et ainsi de suite...
J'avais besoin de l'impression de cette valeur, de sorte que j'ai simplement divisé par 256 et il a été fait. Cependant, si j'utilise le WEXITSTATUS() macro, je vais également obtenir cette valeur comme je le veux...
J'ai regardé de code source C et c'est ce que j'ai trouvé:
#define __WEXITSTATUS(status) (((status) & 0xff00) >> 8)
Je comprends ce qui se passe ici, par exemple, 512 en binaire est de 10 0000 0000, un décalage de 8 o la droite pour donner 00 0000 0010, qui est de 2 en décimal. Ce que je ne comprends pas dans cette macro, c'est que & opérateur et le fait que 0xff00 semble un nombre aléatoire (il n'est probablement pas le cas, d'où vient-elle?). À quoi ça sert exactement, pourquoi il y a "& 0xff00" dans la macro? Ne serait-il pas travailler avec elle?
Et la vraie question dans cette rubrique, c'est la même chose pour appeler cette macro dans mon code comme une division par 256?
OriginalL'auteur Ricardo Amaral | 2009-04-30
Vous devez vous connecter pour publier un commentaire.
Il sera probablement toujours le cas dans le cas où le processus fils se termine normalement (c'est à dire, par appel à exit(), non pas par une erreur de segmentation, l'échec d'assertion, etc.).
Le statut stockées par
waitpid()
code pour la raison que le processus de l'enfant a été résilié, et le code de sortie. La raison en est stocké dans l'octet le moins significatif (obtenu parstatus & 0xff
), et le code de sortie est stockée dans l'octet suivant (masqué parstatus & 0xff00
et extraites parWEXITSTATUS()
). Lorsque le processus se termine normalement, la raison en est 0 et doncWEXITSTATUS
est tout simplement équivalent à un changement de 8 (ou de la division par 256). Cependant, si le processus est tué par un signal (comme SIGSEGV), il n'y a pas de code de sortie, et vous devez les utiliserWTERMSIG
pour extraire le numéro du signal à partir de la raison d'octets.OriginalL'auteur Nathan Kitchen
Si la variable d'état est un entier signé de 16 bits (un "court") sur une machine où le " int " est un 32 bits, et si le statut de sortie est comprise entre 128..255, puis WEXITSTATUS() vous offre une valeur correcte où la division par 256 ou le simple fait de transférer le droit de vous donner une valeur incorrecte.
C'est parce que le court sera signe étendu à 32 bits, et le masquage annule l'opération de l'extension du signe, laissant le bon (positive) de la valeur dans le résultat.
Si la machine utilisée entiers de 16 bits, le code WEXITSTATUS() serait probablement faire shift puis masque afin d'assurer un comportement similaire:
C'est parce que la mise en œuvre prend soin de ces détails pour vous que vous devez utiliser le WEXITSTATUS() macro.
OriginalL'auteur Jonathan Leffler
Aussi loin que je peux dire à partir de la vérification de la Single Unix Spec, votre système arrive à stocker l'état de sortie de la deuxième à droite octet, mais je ne crois pas la norme. Donc, vous devez utiliser les macros pour au moins quelques raisons:
WEXITSTATUS
. Moins avec d'autres approches. Si vous avez vu le roulé à la main version deWIFSIGNALED
, auriez-vous la reconnaître? Combien de temps cela prendrait-il queWIFSIGNALED
.OriginalL'auteur derobert
Ici 0xff00 est un masque binaire (texte du lien). ANDing avec une valeur fixe tous les bits à zéro, à l'exception de la deuxième octet (en partant de la droite).
Vous ne devez utiliser
WEXITSTATUS
sur un processus qui est connu pour avoir sorti normalement. Cette information est donnée par leWIFEXITED
macro.La macro rend le code plus lisible, et il est garanti pour fonctionner sur tout conforme à Posix mise en œuvre. Autant que je sache Posix ne précise pas le format de l'état, de sorte que vous ne pouvez pas attendre de votre code fonctionne partout.
OriginalL'auteur Bastien Léonard