Поставщик компилятора, который хочет написать соответствующий компилятор, связан с тем, что говорит стандарт, но не с вашими соображениями. Стандарт гласит, что индекс массива вне диапазона является неопределенным поведением, без каких-либо исключений , поэтому компилятору разрешается взрываться.
Цитировать мой комментарий из нашего последнего обсуждения ( Гарантирует ли C99, что массивы смежны? )
"Ваш первоначальный вопрос был для a[0][6]
, с объявлением char a[5][5]
. Это UB, несмотря ни на что. Допустимо использовать char *p = &a[3][4];
и доступ p[0]
к p[5]
. Получение адреса &p[6]
все еще действителен, но доступ к p[6]
находится вне объекта, то есть UB. Доступ к a[0][6]
находится вне объекта a[0]
, который имеет массив типов [5] из символов. Тип результата не имеет значения , важно, как вы его достигнете. "
EDIT:
Существует достаточно случаев неопределенного поведения, когда вам приходится просматривать весь Стандарт, собирать факты и объединять их, чтобы, наконец, прийти к выводу о неопределенном поведении. Это явное , и вы даже цитируете предложение Стандарта в своем вопросе. Он явный и не оставляет места для обходных путей.
Мне просто интересно, сколько еще ясности в рассуждениях вы ожидаете от нас, чтобы убедиться, что это действительно UB?
РЕДАКТИРОВАТЬ 2:
После ознакомления со Стандартом и сбора информации, есть еще одна релевантная цитата:
6.3.2.1 - 3: За исключением случаев, когда это операнд оператора sizeof или
унарный оператор &, или строка
литерал, используемый для инициализации массива,
выражение, которое имеет тип ‘‘ массив
тип ’’ преобразуется в выражение
с типом «указатель на тип», который
указывает на начальный элемент
объект массива и не является значением l . Если
объект массива имеет хранилище регистров
класс, поведение не определено.
Так что я думаю, что это действительно:
unsigned char *p = a[1];
unsigned char c = p[7]; // Strict aliasing not applied for char types
Это UB:
unsigned char c = a[1][7];
Потому что a[1]
не является lvalue в этой точке, но оценивается далее, нарушая J.2 с индексом массива вне диапазона. Что в действительности происходит, должно зависеть от того, как компилятор на самом деле реализует индексирование массива в многомерных массивах. Таким образом, вы можете быть правы, что это не имеет никакого значения для каждой известной реализации. Но это также допустимое неопределенное поведение. ;)