const

変更できない定数

const int a = 0;

変更できない定数

int const a = 0;

値を変更できない

const int* a = 0;
a = NULL;

値を変更できない

int const* a = 0;
a = NULL;

好き放題
*1
*2

int* a = NULL;

参照先を変更できない。const は 常に左側に係る

int *const a = 0;
a = 3;

ポインタ型への参照先を変更できない

int**const a = new int*[10]; // int配列をつくり、アドレスを返す
*a = NULL;
a[5] = NULL;

const が先頭に来る書き方を見慣れているが、C,C++の場合むしろ例外的である。
Javaは常に右側へ係るようになっている

const int a = 9;

本題

// アドレスは変更できるが、内部のint値、配列は変更しません宣言
void func (int const*const* val);

int main (int, char**) {
    // arrayポインタは常に同じ場所を参照する
    int**const array_pointer = new int*[5];
    // 値を設定
    for (int i=0; i<5; ++i) *(array_pointer[i]) = new int[2];
// 型が違うのでエラー    
//     func (array_pointer); 
}

事前条件をより厳しくしているだけなので、何の問題もないと思っていたが同じ型として認識されていない。

ルールは
いちばん右のポインタを無視して(左辺のいちばん右のポインタは、値を代入するので今回の場合constではいけない)、
左から見ていき、CV修飾詞が異なっていた場合、
それ以降がconstになっていれば変換可能である。

	char *const *const *const * ncccn = 0;
	char *const **const * ncncn = 0;
	char *const **const *const ncncc = 0;
	char *const ***const ncnnc = 0;
	char *const *** ncnnn = 0;
	char **const *const * nnccn = 0;
	char ***const * nnncn = 0;
	char **const *const *const nnccc = 0;
	char *const *const *const *const ncccc = 0;
	char **const ** nncnn = 0;
	char **const **const nncnc = 0;
	char ***const *const nnncc = 0;
	char ****const nnnnc = 0;
	char **** nnnnn = 0;
	char const*const *const *const * ccccn = 0;
	char const*const **const * ccncn = 0;
	char const*const **const *const ccncc = 0;
	char const*const ***const ccnnc = 0;
	char const*const *** ccnnn = 0;
	char const**const *const * cnccn = 0;
	char const**const *const *const cnccc = 0;
	char const**const ** cncnn = 0;
	char const**const **const cncnc = 0;
	char const***const *const cnncc = 0;
	char const****const cnnnc = 0;
	char const**** cnnnn = 0;

	ncccn = nnnnc;
//	nnccn = ncnnc;

*1:int *aと書く人もいるが、あくまで型がintのポインタなのだからint* a と書くべきだと思う

*2:int *a, *b こう書かないとポインタにならないのは間違った仕様だと思う