Como no UNIX / POSIX, o código de saída de um programa é definido como um valor de 8 bits não assinado. A conversão de -1 em 8 bits não assinados fornece 255.
Edite para adicionar:
Para fornecer mais detalhes: a família de chamadas wait * () do sistema no UNIX codifica o resultado de um processo em um único inteiro de 32 bits. Os 32 bits desse resultado são desmembrados 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 sã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 recursos mais antigos e profundamente incorporados; se você estava projetando um novo sistema operacional hoje, pode fazer algo diferente (pelo menos use 64 bits :-)).
Por outro lado, na prática, é realmente útil ter> 255 códigos de saída? Eu duvido. Se você realmente deseja algo mais poderoso, sugiro que você mude para uma "string de saída", em vez de um código de saída numérico com um intervalo maior.