|
virtual methods
|
|||
---|---|---|---|
#18+
a guestrdb_devпропущено... Давай-ка я перевормулирую поточнееДавай просто возьмём формулировку из стандарта. Это будет самой точной формулировкой, по определению. И мучаться, выдумывать что-то не надо.Давай ка ты сейчас не заглядывая в текст стандарта процитируешь его слово в слово? ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2018, 01:04 |
|
virtual methods
|
|||
---|---|---|---|
#18+
Barlonerdb_devпропущено... Угу! Осталось объяснить это тем, кто пишет boost, компиляторы машинных кодов, потроха операционных систем, драйверы и прочим оптимизаторам.Ну-ка покажите пример из boost/потрохов операционных систем, который с точки зрения стандарта С++ приводил бы к UB...Вот более очевидный пример: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8.
Хоть буст и говорит, что "[data(),data() + size()) is a valid range" с точки зрения стандарта это мало что значит. Вот такое, например Код: plaintext 1. 2.
UB. Конечно, UB как бы в пользовательском коде, т.к. он делает недопустимые операции. Но смысл в том, что переписать boost так, чтобы в использующем его коде не было UB — невозможно в принципе . Поэтому можно сказать, что UB в бусте. ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2018, 01:05 |
|
virtual methods
|
|||
---|---|---|---|
#18+
a guestЯ так понял, ты обиделся и перешёл на личности.Неа! На что тут обижаться? На то, что ты тычешь мне в нос текст стандарта, который не способен заучить наизусть? Да брось! :) Людей, способных запомнить весь текст стандарта слово в слово во всём мире по пальцам сосчитать. Я не переходил на личности, а продемонстрировал разный подход к прохождению обучения в принципе, а не конкретно по отношению к кому-то. ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2018, 01:07 |
|
virtual methods
|
|||
---|---|---|---|
#18+
a guestДаже если в векторе, скажем, 5 элементов, доступ к третьему элементу с таким определением оператора[] как в бусте скорее всего приведёт к UB. Еще раз. Не будет UB. Даже если, как вы привели в том втором примере, каждый элемент вектора создавался отдельно через placement new, и "Никакого массива из int-ов в буфере нет. " . Потому что согласно стандарту expr[i] эквивалентно *(expr + i), и никакой массив тут и не требуется. Достаточно чтобы там, по вычисленному адресу, который разыменовывается, был валидный объект, и он там есть. А вот это ваше " т.к. индексация == адресная арифметика, а она определена только в пределах массива. " - вообще ни на чем не основано. Нет такого ограничения. ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2018, 01:31 |
|
virtual methods
|
|||
---|---|---|---|
#18+
a guestBasil A. Sidorov, ладно, объясняю на пальцах. Пусть тип элемента вектора T = int. Вот есть у нас кусок памяти под 4 элемента (для простоты — статический массив): Код: plaintext 1.
Пусть в векторе 3 элемента 5, 10, 33. Их вектор создал с помощью placement new: Код: plaintext 1. 2. 3.
Теперь что примерно делает оператор[]? Вот это Код: plaintext 1. 2. 3. 4.
А это точно приведёт к UB для n == 2, т.к. индексация == адресная арифметика, а она определена только в пределах массива. Никакого массива из int-ов в буфере нет. Нет здесь никакого UB ни при buffer[2], ни при buffer[3], ни даже при buffer[15], так как массив типа unsigned char создан на 16 элементов и каждый следующий buffer[n+1] это следующий unsigned char, а не int. Конечно, ты можешь инициализировать этот массив как тебе заблагорассудится! Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9.
... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2018, 01:31 |
|
virtual methods
|
|||
---|---|---|---|
#18+
a guestrdb_devНу так одним из частных случаев prvalue и есть нереферальный результат lvalue-to-rvalueМы обсуждали value category оператора *.Мы обсуждали взятие адреса - & BarloneНу разработчики компилятора могут себе такое позволить в исходниках rtl, идущей в комплекте с конкретной версией компилятора. Потому что если в следующей версии компилятора поведение изменится, вместе с компилятором перепишут и rtl. Да, реально видел такое в системных заголовках: Код: plaintext 1.
С точки зрения стандарта, разыменование нулевого указателя - UB. Но разработчик компилятора знает, что в данной конкретной версии так можно. А в следующей минорной версии там может оказаться Код: plaintext 1.
Так что в прикладном коде такие трюки нельзя, если конечно не прибивать гвоздями к конкретному релизу конкретного компилятора, потому что такое может сломаться при любом обновлении. ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2018, 01:36 |
|
virtual methods
|
|||
---|---|---|---|
#18+
Anatoly MoskovskyПотому что согласно стандарту expr[i] эквивалентно *(expr + i), и никакой массив тут и не требуется.См. цитату из стандарта ниже. http://eel.is/c draft/expr.add#4 When an expression that has integral type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the expression P points to element x[i] of an array object x with n elements, the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) element x[i+j] if 0≤i+j≤n; otherwise, the behavior is undefined. Likewise, the expression P - J points to the (possibly-hypothetical) element x[i−j] if 0≤i−j≤n; otherwise, the behavior is undefined. Anatoly MoskovskyДостаточно чтобы там, по вычисленному адресу, который разыменовывается, был валидный объект, и он там есть.А вот это ваше "достаточно, чтобы там, по вычисленному адресу, который разыменовывается, был валидный объект" — вообще ни на чём не основано. Нет такого разрешения. Anatoly MoskovskyА вот это ваше " т.к. индексация == адресная арифметика, а она определена только в пределах массива. " - вообще ни на чем не основано. Нет такого ограничения.См. цитату из стандарта выше. ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2018, 01:37 |
|
virtual methods
|
|||
---|---|---|---|
#18+
a guestAnatoly MoskovskyПотому что согласно стандарту expr[i] эквивалентно *(expr + i), и никакой массив тут и не требуется.См. цитату из стандарта ниже. http://eel.is/c draft/expr.add#4When an expression that has integral type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the expression P points to element x[i] of an array object x with n elements, the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) element x[i+j] if 0≤i+j≤n; otherwise, the behavior is undefined. Likewise, the expression P - J points to the (possibly-hypothetical) element x[i−j] if 0≤i−j≤n; otherwise, the behavior is undefined.И? :) Откомпилируй это: 21455918 и наслаждайся! ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2018, 01:41 |
|
virtual methods
|
|||
---|---|---|---|
#18+
rdb_deva guestпропущено... Мы обсуждали value category оператора *.Мы обсуждали взятие адреса - & Я объяснил, из каких соображений в комитете считают применение оператора * к нулевому указателю UB. И ты полез рассказывать, что это применение не приводит к чтению объекта. И предлагать свои определения для lvalue. 1. Ты правда считаешь, что никто (в комитете и вне его) не знает, что применение оператора * не приводит к доступу к объекту и нужно всех упорно просвещать? 2. Если хочешь сделать код не UB переопределяя lvalue, лучше сделать это в виде предложения в стандарт, а не обижаться тут на форуме. ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2018, 01:42 |
|
virtual methods
|
|||
---|---|---|---|
#18+
http://eel.is/c draft/expr.add#4If the expression P points to element x[i] of an array object x with n elements ... Этот пункт стандарта относится к массивам. А вы сами сказали, что "Никакого массива из int-ов в буфере нет. " Зачем на него ссылаетесь? ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2018, 01:43 |
|
virtual methods
|
|||
---|---|---|---|
#18+
Anatoly Moskovsky http://eel.is/c draft/expr.add#4If the expression P points to element x[i] of an array object x with n elements ... Этот пункт стандарта относится к массивам. А вы сами сказали, что "Никакого массива из int-ов в буфере нет. " Зачем на него ссылаетесь? Затем, что дальше написано, что otherwise behavior is undefined. Массива нет — значит при адресной арифметике получается UB. Вроде вопрос был откуда я взял что там UB и откуда требование про массив. Я ответил. Или опять не ясно? ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2018, 01:45 |
|
virtual methods
|
|||
---|---|---|---|
#18+
Anatoly Moskovsky http://eel.is/c draft/expr.add#4If the expression P points to element x[i] of an array object x with n elements ... Этот пункт стандарта относится к массивам.Этот пункт стандарта относится к арифметике указателей. А других-то пунктов и нет =) ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2018, 01:46 |
|
virtual methods
|
|||
---|---|---|---|
#18+
a guestrdb_devМы обсуждали взятие адреса - & Я объяснил, из каких соображений в комитете считают применение оператора * к нулевому указателю UB. И ты полез рассказывать, что это применение не приводит к чтению объекта. И предлагать свои определения для lvalue.Что за бред?! Дашь ссылку на комментарий, где я изрёк подобную бредятину? Смотри сюда: 21455820 rdb_deva guestКакой объект обозначает это lvalue, если оно применено к нулевому указателю?Какой тип указателя используешь, такой объект там и будет подразумеваться компилятором. Что у нас там в далёком прошлом под DOS'ом располагалось в самом начале адресного пространства процессора Intel 8086? Таблица векторов прерываний (функций BIOS и DOS вызываемых машинной командой int)? А что располагается сейчас в адресном пространстве пользовательского процесса Windows? 64кБ read-only памяти, каждый байт, которой, проинициализирован значением 0x00?Достаточно аргументированно? ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2018, 01:48 |
|
virtual methods
|
|||
---|---|---|---|
#18+
rdb_deva guestпропущено... Я объяснил, из каких соображений в комитете считают применение оператора * к нулевому указателю UB. И ты полез рассказывать, что это применение не приводит к чтению объекта. И предлагать свои определения для lvalue.Что за бред?! Дашь ссылку на комментарий, где я изрёк подобную бредятину? 21455748 Или в " И никакого доступа, приводящего к UB " под "доступом" не имелась в виду попытка чтения из объекта? ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2018, 01:50 |
|
virtual methods
|
|||
---|---|---|---|
#18+
a guestЭтот пункт стандарта относится к массивам.Этот пункт стандарта относится к арифметике указателей. А других-то пунктов и нет =)[/quot]Просто загляни в "legacy" - в стандарт ANSI C и внимательно изучи что такое массив и как работает арифметика типизированных указателей. ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2018, 01:50 |
|
virtual methods
|
|||
---|---|---|---|
#18+
rdb_deva guestЭтот пункт стандарта относится к массивам.Этот пункт стандарта относится к арифметике указателей. А других-то пунктов и нет =)Просто загляни в "legacy" - в стандарт ANSI C и внимательно изучи что такое массив и как работает арифметика типизированных указателей.[/quot] А при чём тут стандарт C, если обсуждается стандарт C++? Впрочем, в стандарте C то же самое написано: арифметика указателей разрешена внутри массива When an expression that has integer type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the pointer operand points to an element of an array object , and the array is large enough, the result points to an element offset from the original element such that the difference of the subscripts of the resulting and original array elements equals the integer expression. In other words, if the expression P points to the i-th element of an array object, the expressions (P)+N (equivalently, N+(P)) and (P)-N (where N has the value n) point to, respectively, the i+n-th and i−n-th elements of the array object, provided they exist. Moreover, if the expression P points to the last element of an array object, the expression (P)+1 points one past the last element of the array object, and if the expression Q points one past the last element of an array object, the expression (Q)-1 points to the last element of the array object. If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined . If the result points one past the last element of the array object, it shall not be used as the operand of a unary * operator that is evaluated. Что теперь скажешь? ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2018, 01:53 |
|
virtual methods
|
|||
---|---|---|---|
#18+
a guestИли в " И никакого доступа, приводящего к UB " под "доступом" не имелась в виду попытка чтения из объекта?Какой может быть UB при выполнении команд процессора из откомпилированного бинарного файла? Там уже исключения... :) ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2018, 01:53 |
|
virtual methods
|
|||
---|---|---|---|
#18+
a guestА при чём тут стандарт C, если обсуждается стандарт C++?А при том, что ANSI C, это LEGACY С++ (читай как "наследство с обременением"). a guestВпрочем, в стандарте C то же самое написано: арифметика указателей разрешена внутри массиваМассивом может быть что угодно. Любой объект можно представить как массив байт, таблицу виртуальных методов можно представить как массив векторов и т.д. и т.п. Для этого даже не обязательно описывать как массив то, что ты хочешь представить как массив. ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2018, 01:58 |
|
virtual methods
|
|||
---|---|---|---|
#18+
rdb_deva guestВпрочем, в стандарте C то же самое написано: арифметика указателей разрешена внутри массиваМассивом может быть что угодно. Любой объект можно представить как массивЯ уже понял, что у тебя что угодно может быть чем угодно. Только мы тут C++ обсуждаем. ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2018, 02:02 |
|
virtual methods
|
|||
---|---|---|---|
#18+
a guestМассивом может быть что угодно. Любой объект можно представить как массивЯ уже понял, что у тебя что угодно может быть чем угодно. Только мы тут C++ обсуждаем.[/quot]Это не у меня, это всегда так было и в C++, и в Си. Именно поэтому на Си до сих пор пишут внутренности операционных систем, прошивки контроллеров и прочую низкоуровневую фигню. :) Ты, случайно, не преподаватель в школе или ВУЗе? ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2018, 02:11 |
|
virtual methods
|
|||
---|---|---|---|
#18+
a guestrdb_deva guestМассивом может быть что угодно. Любой объект можно представить как массивЯ уже понял, что у тебя что угодно может быть чем угодно. Только мы тут C++ обсуждаем.Это не у меня, это всегда так было и в C++, и в Си. Именно поэтому на Си до сих пор пишут внутренности операционных систем, прошивки контроллеров и прочую низкоуровневую фигню. :) Ты, случайно, не преподаватель в школе или ВУЗе?После того, как тебе предъявили цитату из стандарта C, в который ты просил посмотреть, ты начал нести какую-то чушь. Я думаю в таком виде продолжать беседу не имеет смысла. От тебя конкретики 0, только переходы на личности и виляния в сторону. ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2018, 02:17 |
|
virtual methods
|
|||
---|---|---|---|
#18+
a guestПосле того, как тебе предъявили цитату из стандарта C, в который ты просил посмотреть, ты начал нести какую-то чушь. Я думаю в таком виде продолжать беседу не имеет смысла. От тебя конкретики 0, только переходы на личности и виляния в сторону.Для начала, прочти, что представляет из себя массив, почему к нему можно обращаться как к указателю, как осуществляется арифметика типизированных указателей и проверь всё это в отладчике. Потом придёшь и будешь спорить. Ok? :) ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2018, 02:23 |
|
virtual methods
|
|||
---|---|---|---|
#18+
a guestЗатем, что дальше написано, что otherwise behavior is undefined. Массива нет — значит при адресной арифметике получается UB. Вроде вопрос был откуда я взял что там UB и откуда требование про массив. Я ответил. Или опять не ясно?Любой типизированный указатель, формально, уже массив. Такая уж особенность у Си и C++... Другое дело, что в реальности никакого массива там может не быть из-за ошибки программиста, но компилятору об этом, порой, ничего не известно. Попробуй найти потенциальную ошибку в этом простом примере: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.
... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2018, 03:01 |
|
virtual methods
|
|||
---|---|---|---|
#18+
a guestBasil A. SidorovЯ повторю, что? насколько мне известно, placement new вообще ничего не делает с переданным ему буфером.А зачем он нужен, если ничего не делает? Можно не вызвать его тогда... Так это, placement new конструкторы вызывает. ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2018, 07:42 |
|
|
start [/forum/topic.php?fid=57&msg=39652941&tid=2017692]: |
0ms |
get settings: |
10ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
39ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
60ms |
get tp. blocked users: |
1ms |
others: | 265ms |
total: | 411ms |
0 / 0 |