Поставщик компилятора, который хочет написать соответствующий компилятор, привязан к тому, что говорится в Стандарте, но не к вашим рассуждениям. Стандарт говорит, что индекс массива вне допустимого диапазона является неопределенным поведением, без каких-либо исключений, поэтому компилятор может взорваться.
Чтобы процитировать мой комментарий из нашего последнего обсуждения (Гарантирует ли 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] символов. Тип результата не имеет значения, важно, как вы его достигнете ».
РЕДАКТИРОВАТЬ:
Есть достаточно случаев неопределенного поведения, когда вам нужно просмотреть весь стандарт, собрать факты и объединить их, чтобы наконец прийти к выводу о неопределенном поведении. Это явный, и вы даже цитируете предложение из Стандарта в своем вопросе. Он явный и не оставляет места для каких-либо обходных путей.
Мне просто интересно, насколько большей ясности в рассуждениях вы ожидаете от нас, чтобы мы убедились, что это действительно UB?
РЕДАКТИРОВАТЬ 2:
После того, как мы покопались в Стандарте и собрали информацию, вот еще одна важная цитата:
6.3.2.1 - 3: За исключением случаев, когда это операнд оператора sizeof или унарного оператора &, или строковый литерал, используемый для инициализации массива, выражение, имеющее тип "массив типа", преобразуется в выражение с типом "указатель на тип", который указывает на начальный элемент объекта массива, а не является lvalue. Если объект массива имеет класс хранения регистров, поведение не определено.
Так что я думаю, что это действительно так:
unsigned char *p = a[1];
unsigned char c = p[7]; // Strict aliasing not applied for char types
Это УБ:
unsigned char c = a[1][7];
Потому что a[1]
не является lvalue в этот момент, но оценивается дальше, нарушая J.2 с индексом массива вне допустимого диапазона. Что на самом деле происходит, должно зависеть от того, как компилятор на самом деле реализует индексацию массивов в многомерных массивах. Возможно, вы правы в том, что это не имеет никакого значения для каждой известной реализации. Но это тоже допустимое неопределенное поведение. ;)
person
Secure
schedule
22.09.2010
unsigned char
не применима также к примеруint
, описанному в стандарте? - person eldarerathis   schedule 22.09.2010int
или некоторого другого типа, который перекрывает его, приводит к неопределенному поведению. Единственные типы, которые можно использовать таким образом, - это символьные типы (char
,signed char
иunsigned char
). - person R.. GitHub STOP HELPING ICE   schedule 22.09.2010