型修飾子

前にデータ型修飾子というのが出てきた。「型修飾子」は名前が似てて紛らわしいけど、別のもの。変数を宣言するときに、その変数の性質をコンパイラに伝えることができる。

const

宣言時に型の前に const をつけると、その変数はプログラム中で変更できなくなる。ただし、宣言時に初期化することはできる。次の例は正しい例。

#include

int main(void)
{
    const int i = 10;

    printf("%d\n", i);

    return 0;
}
takatoh@nightschool $ ./sample_11_2a
10

こっちは正しくない例。コンパイル時に read-only の変数に代入しているというエラーが出ている。

#include

int main(void)
{
    const int i = 10;

    i = 20;
    printf("%d\n", i);

    return 0;
}
takatoh@nightschool $ gcc sample_11_2b.c -o sample_11_2b
sample_11_2b.c: In function ‘main’:
sample_11_2b.c:8:5: error: assignment of read-only variable ‘i’
     i = 20;
     ^

宣言時に初期化しないで、あとから代入したらどうだろう?

#include

int main(void)
{
    const int i;

    i = 20;
    printf("%d\n", i);

    return 0;
}
takatoh@nightschool $ gcc sample_11_2c.c -o sample_11_2c
sample_11_2c.c: In function ‘main’:
sample_11_2c.c:8:5: error: assignment of read-only variable ‘i’
     i = 20;
     ^

同じエラーが出た。const で修飾した変数は、宣言時に初期化しないといけない。

volatile

宣言時に、型の前に volatile をつけると、その変数がプログラム中で明示されない方法で変更される可能性があることを、コンパイラに伝えることになる。「プログラム中で明示されない方法」というのは、例えば外部からの割り込みによって変更されるような場合だ。
コンパイラはプログラムをコンパイルするときに最適化を行うけど、volatile で修飾された変数は参照するたびに内容を調べ直すようになる。