Qualquer vantagem em utilizar WEXITSTATUS macro em C sobre a divisão por 256 sobre o estado exit ()?

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

  •  03-07-2019
  •  | 
  •  

Pergunta

Eu estava fazendo um exercício para a universidade onde eu tive que retornar um valor com saída, esse valor foi realmente uma contagem de algo. Isto poderia ser acima de 255 (que exit () não pode lidar com), mas o professor sugeriu a dados de teste de uso, onde a contagem nunca poderia ir acima desse valor.

Depois de tudo isso, eu precisava para lidar com este valor de contagem, o estado de saída, eu tenho esse valor no processo principal usando waitpid (). Para minha surpresa, se o processo filho retornou 1, o valor "real" no processo principal era 256, 2 foi de 512 e assim por diante ...

I para imprimir esse valor então eu simplesmente dividiu por 256 e foi feito. No entanto, se eu usar o macro WEXITSTATUS (), eu vou também obter esse valor do jeito que eu quero ...

Eu olhei para o código-fonte C e isto é o que eu descobri:

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

Eu entendo o que está acontecendo aqui, por exemplo, 512 em binário é 10 0000 0000, deslocando 8 o da direita vai dar 00 0000 0010, que é 2 em decimal. O que eu não entendo nesta macro é que o & operador eo fato de que 0xff00 parece um número aleatório (que provavelmente não é, de onde ela vem embora?). O que isso faz exatamente, por que há "& 0xff00" na macro? que não iria funcionar sem ele?

E a verdadeira questão neste tópico, é a mesma coisa para chamar esta macro no meu código como dividir por 256?

Foi útil?

Solução

E a verdadeira questão neste tópico, é a mesma coisa para chamar esta macro no meu código como dividir por 256?

É provavelmente sempre trabalho nos casos em que o processo filho termina normalmente (ou seja, chamando exit (), e não por uma falha de segmentação, falha de declaração, etc.).

O status armazenadas por waitpid() codifica tanto a razão pela qual o processo filho foi terminado e o código de saída. A razão é armazenado no byte menos significativo (obtido por status & 0xff), e o código de saída são armazenados no próximo byte (mascarado por status & 0xff00 e extraiu-se por WEXITSTATUS()). Quando o processo termina, normalmente, a razão é 0 e por isso WEXITSTATUS é simplesmente equivalente ao deslocamento por 8 (ou dividir por 256). No entanto, se o processo é morto por um sinal (como SIGSEGV), não há código de saída, e você tem que usar WTERMSIG para extrair o número do sinal a partir do byte razão.

Outras dicas

Se a variável de estado é um número inteiro de 16-bits com sinal (um 'curto') em uma máquina onde 'int' é uma quantidade de 32 bits, e se o estado de saída está na gama 128..255, então WEXITSTATUS () ainda lhe dá um valor correcto onde dividir por 256, ou simplesmente mudando direito lhe dará um valor incorreto.

Isso ocorre porque o curta será sinal estendido para 32-bits, e o mascaramento desfaz a extensão do sinal, deixando o valor correto (positivo) no resultado.

Se a máquina usada inteiros de 16 bits, então o código em WEXITSTATUS () provavelmente faria turno, em seguida, máscara para garantir um comportamento semelhante:

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

É porque a implementação cuida desses detalhes para você que você deve usar a macro WEXITSTATUS ().

Tanto quanto eu posso dizer de verificar o único Unix Spec, o sistema acontece para armazenar o estado de saída na segunda-to-mais à direita octeto, mas eu não acredito que padrão faz. Então, você deve usar as macros para pelo menos algumas razões:

  • Eles estão corretos. Bit de mudança de um número negativo faz coisas diferentes em diferentes plataformas. Será que funciona da maneira que quiser no seu? Eu não sei.
  • Eles são simples. Sua imediatamente claro o que WEXITSTATUS faz. Menos com outras abordagens. Se você viu a versão enrolado à mão de WIFSIGNALED, você iria reconhecê-lo? Quanto tempo seria necessário que WIFSIGNALED.
  • Eles são portáteis. Desde a sua como a especificação diz fazê-lo, ele vai trabalhar em todos os sistemas (pelo menos praticamente todos os Unix-like sistema).

Aqui 0xff00 é uma máscara binária ( link de texto ). Anding-lo com um valor define todos os bits a zero, exceto o segundo byte (a contar da direita).

Você só deve usar WEXITSTATUS em um processo que é conhecido por ter terminado normalmente. Esta informação é dada pela macro WIFEXITED.

E a verdadeira questão neste tópico, é a mesma coisa para chamar esta macro no meu código como dividir por 256?

A macro torna o código mais legível, e é garantida para trabalhar em qualquer aplicação compatível com POSIX. Tanto quanto eu sei que Posix não especificar o formato do estado, então você não pode esperar que seu código para trabalhar em todos os lugares.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top