¿Algún beneficio al usar la macro WEXITSTATUS en C sobre la división por 256 en el estado de exit ()?

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

  •  03-07-2019
  •  | 
  •  

Pregunta

Estaba haciendo un ejercicio para la universidad donde tuve que devolver un valor con exit, ese valor era en realidad un conteo de algo. Esto podría estar por encima de 255 (que exit () no puede manejar) pero el profesor sugirió usar datos de prueba donde el conteo nunca podría superar ese valor.

Después de todo esto, necesitaba manejar este valor de conteo, el estado de salida, obtuve este valor en el proceso principal mediante el uso de waitpid (). Para mi sorpresa, si el proceso hijo devolvió 1, el " real " el valor en el proceso principal fue 256, 2 fue 512 y así sucesivamente ...

Necesitaba imprimir este valor, así que simplemente lo dividí por 256 y se hizo. Sin embargo, si uso la macro WEXITSTATUS (), también obtendré este valor de la forma que quiero ...

Miré el código fuente de C y esto es lo que descubrí:

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

Entiendo lo que está sucediendo aquí, por ejemplo, 512 en binario es 10 0000 0000, cambiando 8 o la derecha dará 00 0000 0010, que es 2 en decimal. Lo que no entiendo en esta macro es que & amp; operador y el hecho de que 0xff00 parece un número aleatorio (probablemente no lo sea, ¿de dónde viene?). ¿Qué hace exactamente esto, por qué hay " & amp; 0xff00 " en la macro? ¿No funcionaría sin él?

Y la pregunta real en este tema, ¿es lo mismo que llamar a esta macro en mi código que dividir por 256?

¿Fue útil?

Solución

  

Y la verdadera pregunta en este tema,   Es lo mismo que llamar a esta macro.   en mi código como dividir por 256?

Probablemente siempre funcionará en los casos en que el proceso hijo finaliza normalmente (es decir, llamando a exit (), no por un error de segmentación, un error de aserción, etc.).

El estado almacenado por waitpid () codifica la razón por la que se terminó el proceso hijo y el código de salida. El motivo se almacena en el byte menos significativo (obtenido por status & amp; 0xff ), y el código de salida se almacena en el siguiente byte (enmascarado por status & amp; 0xff00 y extraído por WEXITSTATUS () ). Cuando el proceso termina normalmente, el motivo es 0 y, por lo tanto, WEXITSTATUS es simplemente equivalente a cambiar entre 8 (o dividir entre 256). Sin embargo, si el proceso es eliminado por una señal (como SIGSEGV), no hay un código de salida, y tiene que usar WTERMSIG para extraer el número de señal del byte de la razón.

Otros consejos

Si la variable de estado es un entero de 16 bits con signo (un 'corto') en una máquina donde 'int' es una cantidad de 32 bits, y si el estado de salida está en el rango 128..255, entonces WEXITSTATUS () aún le da un valor correcto donde dividir por 256 o simplemente desplazarse hacia la derecha le dará un valor incorrecto.

Esto se debe a que el signo corto se extenderá a 32 bits y el enmascaramiento deshace la extensión del signo, dejando el valor correcto (positivo) en el resultado.

Si la máquina usaba enteros de 16 bits, entonces el código en WEXITSTATUS () probablemente cambiaría y luego se enmascararía para asegurar un comportamiento similar:

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

Debido a que la implementación se encarga de esos detalles, debes usar la macro WEXITSTATUS ().

Por lo que puedo decir al verificar la especificación de Unix único, su sistema almacena el estado de salida en el octeto del segundo a la derecha, pero no creo que el estándar sí lo hace. Por lo tanto, debe usar las macros por al menos algunas razones:

  • Son correctos. Cambiar un número negativo a bits hace diferentes cosas en diferentes plataformas. ¿Funciona como quieres en el tuyo? No lo sé.
  • Son simples. Es inmediatamente claro lo que hace WEXITSTATUS . Menos con otros enfoques. Si viera la versión enrollada a mano de WIFSIGNALED , ¿lo reconocería? ¿Cuánto tiempo tomaría más que WIFSIGNALED .
  • Son portátiles. Dado que es como dice la especificación para hacerlo, funcionará en todos los sistemas (al menos en casi todos los sistemas tipo Unix).

Aquí 0xff00 es una máscara binaria ( texto del enlace ). Y, con un valor, todos los bits se ponen a cero, excepto el segundo byte (contando desde la derecha).

Solo debe usar WEXITSTATUS en un proceso que se sabe que ha salido normalmente. Esta información la proporciona la macro WIFEXITED .

  

Y la pregunta real en este tema, ¿es lo mismo que llamar a esta macro en mi código que dividir por 256?

La macro hace que el código sea más legible y está garantizado para trabajar en cualquier implementación compatible con Posix. Que yo sepa, Posix no especifica el formato del estado, por lo que no puede esperar que su código funcione en todas partes.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top