Como no UNIX / POSIX, o código de saída de um programa é definido como um valor de 8 bits sem sinal. Convertendo -1 para unsigned 8-bit dá 255.
Editar para adicionar:
Para dar mais detalhes: a família wait () de chamadas do sistema no UNIX codifica o resultado de um processo em um único inteiro de 32 bits. Os 32 bits desse resultado são divididos para fornecer informações como se o processo despejou o núcleo, saiu devido a um sinal (e qual), etc. Desses 32 bits, apenas 8 estão reservados para o código de saída do processo. e esses são interpretados como um valor não assinado.
O modelo fork / exec / wait do UNIX / POSIX é um dos seus recursos mais antigos e mais profundamente incorporados; Se você estivesse projetando um novo sistema operacional hoje, você pode fazer algo diferente (pelo menos use 64 bits: -)).
Por outro lado, praticamente falando, é realmente útil ter > 255 códigos de saída? Eu duvido. Se você realmente quisesse algo mais poderoso, eu sugeriria que você mudasse para uma "string de saída", em vez de um código de saída numérico com um intervalo maior.