C言語についての記事です。知らない間に8進数を使わないようにしましょう、という注意喚起です。
整数定数の復習
整数定数については、すでに記事にしています。そのまま引用します。
- 整数定数:以下のどれか。後で示す整数接尾語を付けてもよい。
- 10進定数:0以外で始まる。0から9が続く。基数は10
- 8進定数:0で始まる。0から7が続く。基数は8
- 16進定数:0xまたは0Xで始まる。0-9、a-f、A-Fが続く。基数は16
今回の内容は、整数接尾語は関係しません。気になる人は元の記事で説明しています。
どう読める?
次のC言語のコード片を見てください。
int data[4];
data[0] = 000;
data[1] = 020;
data[2] = 100;
data[3] = 300;
// (^_^;
4個の要素を持つ配列 data を初期化しています。プログラムを書いた人は、桁数の見た目を合わせたかったのか、上のように書いていました。
ここで、data[1] は、0から始まっているため8進数(基数8)と解釈されます。このため、data[1] は、プログラマが意図した 20 ではなく、16 になります。
一方、data[0] も8進数となりますが、基数8でも基数10でも、0は0です。
桁数を合わせるためには、0 を差し込むのではなく、空白を差し込んで固定幅フォントを使うようにしましょう。上で紹介した例は、以下となります。
int data[4];
data[0] = 0;
data[1] = 20;
data[2] = 100;
data[3] = 300;
// v(^_^)v
コーディングガイドライン
MISRA C 最新版(2023)の Rule 7.1 では、以下の趣旨のガイドラインを紹介しています。
8進定数を使わないようにしよう。
ただし、0は例外となります。
C言語を使っていても、8進定数の文法自体を知らない場合もあるでしょう。この記事で、少しでも意図しないトラブルが減ればと思います。
最後に
このトラブルについては、「Cプログラミングの落とし穴」(Koenig著、中村明訳)で紹介されていました。原書は1988年出版です。日本語版は再販もされましたが、現在は絶版になっているようです。
C言語を使いこなしていきましょう!