問題の概要
だれがいつ作ったのか、よくわからないC言語のソースコードが発端。
main.c
int main(int argc, char *argv[]) {
// ----------------------------
// よくわからないとても長い処理
//-----------------------------
}
このプログラムの設計書を見ると、以下のように記載されているわけです。
- 正常終了の場合 … 終了ステータス0
- 異常終了の場合 … 終了ステータス999
これを試験するため、C言語を気合でコンパイル。異常終了となるようなインプットを与えて実行したところ、終了ステータスが255となり、設計書とは異なる挙動となりました。
$ gcc main.c
$ ./a.out WRONG_INPUT
$ echo $?
231
原因と対策
ソースコードを読み解いたところ、main関数の終了ステータスが999となっていました。
main.c
int main(int argc, char *argv[]) {
// ----------------------------
// よくわからないとても長い処理
//-----------------------------
int status;
// ----------------------------
// よくわからないとても長い処理
//-----------------------------
status = 999;
// ----------------------------
// よくわからないとても長い処理
//-----------------------------
return status;
}
bashの終了ステータスの範囲は0から255の間で、範囲外の整数がexitに渡された場合、終了ステータスは256の剰余となります (status & 0xFF
)
C言語のバージョン・環境にもよりますが、main関数の戻り値はそのまま終了ステータスとなります。今回の場合、main関数の戻り値が999で、0~256の範囲外ですから、999%256=231
が戻り値となっています。
環境情報
$ gcc --version
gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.6 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.6 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal