Jeder Vorteil bei der Verwendung WEXITSTATUS Makro in C über eine Division durch 256 auf exit () Status?

StackOverflow https://stackoverflow.com/questions/808541

  •  03-07-2019
  •  | 
  •  

Frage

Ich war eine Übung für die Universität zu tun, wo ich mit Ausgang einen Wert zurückgeben musste, war dieser Wert tatsächlich eine Zählung von etwas. Dies vor 255 sein könnte (die exit () nicht verarbeiten kann), aber der Lehrer vorgeschlagen Testdaten zu verwenden, wo die Zählung nie über diesem Wert gehen könnte.

Nach all das, ich brauchte diesen Zählwert zu handhaben, der Exit-Status, bekam ich diesen Wert im Hauptprozess unter Verwendung waitpid (). Zu meiner Überraschung, wenn das Kind Prozess 1 zurückgegeben, der „echte“ Wert im Hauptprozess betrug 256, 2 war 512 und so weiter ...

Ich brauchte diesen Wert zu drucken, so einfach ich es geteilt durch 256, und es wurde getan. Allerdings, wenn ich den WEXITSTATUS () Makro verwenden, ich werde auch diesen Wert den Weg ich es will ...

schaute ich auf C-Quellcode und das ist, was ich herausgefunden habe:

#define __WEXITSTATUS(status) (((status) & 0xff00) >> 8)

Ich verstehe, was hier passiert, zum Beispiel, 512 binär 10 0000 0000, 8 o rechts verschoben wird 00 0000 0010 geben, die 2 in dezimal ist. Was ich in diesem Makro nicht verstehen ist, dass & Betreiber und die Tatsache, dass 0xff00 eine Zufallszahl scheint (es ist wahrscheinlich nicht, woher kommt es aus, obwohl kommen?). Was dies genau macht, warum gibt es „& 0xff00“ im Makro? Wäre es nicht mit heraus es?

Und die eigentliche Frage in diesem Thema, ist die gleiche Sache dieses Makro in meinem Code zu nennen, wie durch 256 dividiert?

War es hilfreich?

Lösung

  

Und die eigentliche Frage in diesem Thema,   ist die gleiche Sache dieses Makro aufrufen   in meinem Code als Division durch 256?

Es wird wahrscheinlich immer in den Fällen arbeiten, wo das Kind Prozess normal beendet wird (das heißt, von dem Aufruf von exit (), nicht durch einen Segmentierungsfehler, Assertionsfehler, usw.).

Der Status von waitpid() gespeichert codiert sowohl den Grund, dass das Kind Prozess beendet wurde und den Exit-Code. Der Grund dafür ist in dem niedrigstwertigen Byte (erhalten durch status & 0xff) gespeichert, und der Beendigungscode wird im nächsten Byte (maskiert durch status & 0xff00 und extrahierte durch WEXITSTATUS()) gespeichert. Wenn der Prozess normal beendet wird, ist der Grund, 0, und so ist nur WEXITSTATUS Äquivalent von 8 bis Verschiebung (oder dividiert durch 256). Wenn jedoch das Verfahren durch ein Signal (wie SIGSEGV) getötet wird, gibt es keinen Exit-Code, und Sie haben WTERMSIG zu verwenden, um die Signal-Nummer aus dem Grunde Byte zu extrahieren.

Andere Tipps

Wenn die Statusvariable ist eine vorzeichenbehaftete 16-Bit-Ganzzahl (a ‚kurz‘) auf einer Maschine, ‚int‘ ist eine 32-Bit-Menge, und wenn der Beendigungsstatus im Bereich 128..255, dann WEXITSTATUS () gibt Ihnen noch einen korrekten Wert in dem durch 256 dividiert oder einfach rechts verschoben werden Ihnen einen falschen Wert geben.

Das ist, weil die kurze bis 32-Bit erweitert werden Zeichen, und die Maskierung rückgängig macht das die Vorzeichenerweiterung, den richtigen (positiven) Wert im Ergebnis zu verlassen.

Wenn die Maschine 16-Bit-Integer verwendet, dann wird der Code in WEXITSTATUS () würde wahrscheinlich maskieren Sie shift dann ein ähnliches Verhalten zu gewährleisten:

#define WEXITSTATUS(status) (((status)>>8) & 0xFF)

Es ist, weil die Umsetzung Pflege solcher Details für Dich nimmt, dass Sie den WEXITSTATUS () Makro verwenden sollen.

Soweit ich von der Überprüfung der Single Unix Spec sagen kann, Sie System passiert den Exit-Status in dem zweiten zu ganz rechts Oktett zu speichern, aber ich glaube nicht, der Standard tut. Also, sollten Sie die Makros für mindestens ein paar Gründe verwenden:

  • Sie sind richtig. Bit-Verschiebung eine negative Zahl macht verschiedene Dinge auf verschiedenen Plattformen. Funktioniert es so, wie Sie auf Sie wollen? Ich weiß es nicht.
  • Sie sind einfach. Seine sofort klar, welche WEXITSTATUS tut. Weniger mit anderen Ansätzen. Wenn Sie die handgerollte Version von WIFSIGNALED sehen, würden Sie es erkennen? Wie lange würde es als WIFSIGNALED nehmen.
  • Sie sind tragbar. Seit seinem, wie die Spezifikation, es zu tun, sagt, es wird auf jedem System arbeiten (zumindest so ziemlich jedes Unix-System).

Hier 0xff00 ist eine binäre Maske ( Link-Text ). AND-Verknüpfung mit einem Wert setzt alle Bits auf Null, mit Ausnahme des zweiten Byte (von rechts aus gezählt).

Sie sollten nur WEXITSTATUS auf einem Prozess verwendet werden, die normalerweise haben verlassen bekannt ist. Diese Informationen werden von der WIFEXITED Makro gegeben.

  

Und die eigentliche Frage in diesem Thema, ist die gleiche Sache dieses Makro in meinem Code zu nennen, wie durch 256 dividiert?

Das Makro macht den Code besser lesbar, und es ist garantiert auf jeder Posix-konforme Umsetzung zu arbeiten. Soweit ich weiß, Posix nicht das Format des Status angeben, so kann man nicht erwarten, dass Ihr Code überall arbeiten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top