Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Я уверен, Егор это и так знает. Видимо, весь вопрос в волшебном символе &, а точнее в его положении — в одном случае он задает адрес элемента массива, а в другом — адрес всего массива.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, Igore, Вы писали:
I>>Здравствуйте, Erop, Вы писали:
E>>>SUBJ
I>>Не UB, I>>1[array] == array[1], грубо говоря I>>1 + *pointer == *pointer + 1
R>Я уверен, Егор это и так знает. Видимо, весь вопрос в волшебном символе &, а точнее в его положении — в одном случае он задает адрес элемента массива, а в другом — адрес всего массива.
int array[146];
assert( (1[&array] - &array[0]) == 146 );
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, rg45, Вы писали:
R>Я уверен, Егор это и так знает. Видимо, весь вопрос в волшебном символе &, а точнее в его положении — в одном случае он задает адрес элемента массива, а в другом — адрес всего массива.
Именно так. Формально мы ка кбы разыменовываем указатель на место за массивом, но разыменовываем его только для того, что бы преобразовать к адресу нулевого элемента этого несуществующего массива, то есть, фактически,
(typeof(array[0])*)1[&array]
это получение указателя на конец массива.
Вопрос в том, валидно ли такое недоразыменование?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Спасибо за разъяснения. Я верно понял, что с твоей т. з. тут всё нормуль:
int f( int i)
{
return 1[&i];
}
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, rg45, Вы писали:
R>Я уверен, Егор это и так знает. Видимо, весь вопрос в волшебном символе &, а точнее в его положении — в одном случае он задает адрес элемента массива, а в другом — адрес всего массива.
А почему? Ведь &array == array == &array[0]?
И array[1] == 1[array].
Или для array[size] берётся не sizeof(array[0]), а sizeof(array[size])?
Пользуйся, пожалуйста, тэгами [c] тут код [/c]
I>Да уж, проверил
&array[1] != 1[&array]
, получается
Тут скобки не так стоят, как ты думаешь.
&array[1]
/*интерпретируется как */
&(array[1])
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, flаt, Вы писали:
F>А почему?
По грамматике и семантике языка
F>Ведь
&array == array == &array[0]
?
1) первое равенство вообще не имеет места быть,
2) второе просто использует неявное приведение типов, реально тип массива и указателя на нулевой элемент массива отличается, соответственно и результаты операция могут быть разными.
Кстати, печально, что-то, походу, тут только один коллега понял вопрос, но всё равно не знает ответа...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Именно так. Формально мы ка кбы разыменовываем указатель на место за массивом, но разыменовываем его только для того, что бы преобразовать к адресу нулевого элемента этого несуществующего массива, то есть, фактически,
(typeof(array[0])*)1[&array]
это получение указателя на конец массива. E>Вопрос в том, валидно ли такое недоразыменование?
имхо, нет. С указателем на место за массивом никаких проблем нет (это специально оговорено), а вот с его разыменованием — очевидно, есть. То, что он как-то дальше особенным способом используется, рояли не играет. Так что если тебе нужен просто указатель на место за массивом — используй арифметику указателей, с ней никаких проблем. Тем более что тебе доступен размер массива, так как он вшит в его тип (иначе бы твой код не работал вообще).
А зачем вообще это нужно? Какую задачу ты решаешь этим кодом?
Здравствуйте, jazzer, Вы писали:
J>А зачем вообще это нужно? Какую задачу ты решаешь этим кодом?
Встретил на ревью, юзали в качестве lengthof.
Написал, что нестандартно, опасно и не константа времени компиляции + UB.
Попросили аргументировать по UB, так как это а-та-та и депримирование вплоть до увольнения...
В целом я тоже считаю, что это UB, так как 1[&array] -- разыменование.
Но, с другой стороны, это же всего лишь ссылка, у которой потом берут адрес? Ссылку на конец массива получать ведь нельзя? Я верно понимаю?
Я как бы посмотрел стандарт, правда старый, но на вский случай решил проконсультроваться у коллег... Вопрос IMHO крайне казуистический всё-таки.
С другой стороны, просто интересно, насколько это UB реализуемо...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, flаt, Вы писали:
F>Почему? Операция взятия адреса от массива ничего не делает же?
Просто попробуй сравнить адреса
1 + &array
и
1 + array
и подумай делает она что-то или нет...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, flаt, Вы писали:
E>>1) первое равенство вообще не имеет места быть, F>Почему? Операция взятия адреса от массива ничего не делает же?
А ты про какой язык, кстати? Я имел в виду, что первого равенства нет в С++, там типы не приведутся...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, jazzer, Вы писали:
J>>А зачем вообще это нужно? Какую задачу ты решаешь этим кодом?
E>Встретил на ревью, юзали в качестве lengthof. E>Написал, что нестандартно, опасно и не константа времени компиляции + UB.
Согласен. Нафига заниматься жонглированием граблями в рантайме, когда можно пользоваться девайсами времени компиляции типа
(формально тут рантайм-функция, но так как она возвращает константу времени компиляции, любой вменяемый компилятор просто вставит константу; а в С++11 ее вообще constexpr можно объявить)
E>Попросили аргументировать по UB, так как это а-та-та и депримирование вплоть до увольнения... как-то жестковато для простого UB, имхо
E>В целом я тоже считаю, что это UB, так как 1[&array] -- разыменование.
именно:
The expression E1[E2] is identical (by definition) to *((E1)+(E2))
а в статье про оператор разыменования сказано:
The unary * operator performs indirection: the expression to which it is applied shall be a pointer to an
object type, or a pointer to a function type and the result is an lvalue referring to the object or function
to which the expression points.
стало быть, если нет никакого объекта, на который указывает выражение (E1)+(E2), то и поведение не определено.
Это даже не говоря о том, что у разыменованного "объекта" может оказаться свой веселый перегруженный оператор* (а не встроенный), который может вызвать форматирование винчестера и запуск ракет.
E>Но, с другой стороны, это же всего лишь ссылка, у которой потом берут адрес? Ссылку на конец массива получать ведь нельзя? Я верно понимаю?
Это лишь аппеляция к "существующий судебной практике". В том смысле, что "скорее всего ничего не будет, я в дизассемблере посмотрел и поставил свечку, что все компиляторы всегда такой же код генерят".
E>Я как бы посмотрел стандарт, правда старый, но на вский случай решил проконсультроваться у коллег... Вопрос IMHO крайне казуистический всё-таки. E>С другой стороны, просто интересно, насколько это UB реализуемо...
Очень легко. Надо просто помнить про существование интерпретаторов С++, типа cint или cling. Им ничто не мешает отслеживать все разыменования и форматировать винчестер, если что не так
Здравствуйте, flаt, Вы писали:
F>А почему? Ведь &array == array == &array[0]?
Широко распространенное заблуждение. Почему-то людям кажется, что если массив неявно преобразуется к указателю, то адрес массива и сам массив — это одно и тоже Нет. Выражения &array и array имеют разные типы, не подлежащие даже сравнению.
--
Справедливость выше закона. А человечность выше справедливости.