ポインタ変数のconst指定

#include <stdio.h>

char s1[] = "This is array.";
char *s2 = "This is pointer.";

int main()
{
        return 0;
}

このプログラムについて、nmコマンドでシンボルテーブルをダンプしてみると、以下のようになります。2フィールド目の「D」とは、その変数が、.dataセクション(0以外の初期値を持つ広域変数や局所変数が配置されるセクション)に配置されることを意味します。

$ nm pointer
0804a01c D s1
0804a02c D s2

では、s1とs2の先頭に「const」をつけると、どうなるでしょうか。

const char s1[] = "This is array.";
const char *s2 = "This is pointer.";

シンボルテーブルをダンプしてみると、以下のようになります。配列の方(s1)は、「R」ですが、これは.rodataセクション(読み取り専用)に配置されます。しかし、s2の方は、「D」となっています。

$ nm pointer
08048490 R s1
0804a01c D s2

これは、constが「ポインタ変数それ自体」を修飾しているわけではなく、ポインタ変数が指す「領域」("This is pointer."という文字列の領域)をconst指定しているので、s2というポインタ変数自体は、.dataセクションに配置されます。

s2もconst指定したい場合は、

const char s1[] = "This is array.";
const char * const s2 = "This is pointer.";
             ^^^^^

と、「変数名の直前」にconstを記述すると、無事に.rodataセクションに配置されました。

$ nm pointer
08048490 R s1
080484b0 R s2