Ответ 1
В GNU C указатели на массивы с квалификаторами работают аналогично указателям на другие квалифицированные типы. Например, значение типа
int (*)[5]
может использоваться для инициализации переменной типаconst int (*)[5]
. Эти типы несовместимы в ISO C, потому что квалификаторconst
формально привязан к типу элемента массива, а не самому массиву.
Стандарт C говорит, что (раздел: §6.7.3/9):
Если спецификация типа массива включает в себя квалификаторы любого типа, тип элемента имеет соответствующую квалификацию, не тип массива. [...]
Теперь посмотрим на стандарт С++ (раздел § 3.9.3/5):
[...] Cv-квалификаторы, применяемые к типу массива, присоединяются к типу базового элемента, поэтому обозначение "
cv T
", гдеT
является типом массива, относится к массиву, элементы которого являются так называемыми " квалифицированный. Тип массива, чьи элементы имеют квалификацию cv, также считается имеющим те же CV-квалификацию, что и его элементы. [Пример:typedef char CA[5]; typedef const char CC; CC arr1[5] = { 0 }; const CA arr2 = { 0 };
Тип
arr1
иarr2
- это "массив из 5 const char", а тип массива считается const-qual. -endexample]
Следовательно, инициализация
const int (*p2)[9] = &array;
является присвоением указателю типа массиву [9] of int
указателю на массив [9] для const int
. Это не похоже на назначение int *
a const int *
, где const
применяется непосредственно к типу объекта , указатель указывает на. Это не относится к const int(*)[9]
, где в C, const
применяется к элементам объекта массива вместо объекта, на который указывает указатель. Это делает вышеуказанную инициализацию несовместимой.
Это правило изменяется на С++. Поскольку const
применяется к самому объекту массива, назначение находится между теми же типами указателя на const array [9] of int
вместо указателя типа на массив [9] of int
и указателя на массив [9] of const int
.