Re[20]: Когда это наконец станет defined behavior?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 29.04.23 15:51
Оценка:
Здравствуйте, T4r4sB, Вы писали:

R>>А функция bar может может иметь непостредственный доступ к объекту, помимо той ссылки, которая передается в функцию foo:


TB>Надо стандартизаторам идею подкинуть: а почему б такую ситуацию тоже не назвать UB? Типа передали константную ссылку — значит компилятор вправе предполагать что содержимое не меняется! Это ж сколько можно долей процента выиграть в реальных приложениях! А сколько будет новых непонятных падений!


Шутки шутками, а когда я писал позапрошлый комментарий, мне так и казалось. Слишком уж тонкая материя — сейчас смутно вспоминается, что я эту проблему читал, но поскольку сам на грабли не наступал, то оно и забылось.

По-"бытовому" const для объекта как источник предположения, что он не будет меняться, очень полезен. Но вводить его с учётом описанного тут я бы не стал, тут скорее нужно два разных уровня const — один "обещаем что не будет меняться" и второй послабее — запрет изменения через конкретные ссылку/указатель.
Чуть громоздко, но ясность ситуации, думаю, будет важнее.
The God is real, unless declared integer.
Re[21]: Когда это наконец станет defined behavior?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 29.04.23 15:59
Оценка:
Здравствуйте, rg45, Вы писали:

R>Другими словами, ты предлагаешь запретить привязывать константные ссылки к неконстантным объектам? Сомнительная идея как по мне.


Я такого у него не читал.
А вот считать, что раз ссылка константная, то и объект не будет изменяться никем со стороны по крайней мере время жизни этой конкретной ссылки — а почему собственно нет?
The God is real, unless declared integer.
Re[22]: Когда это наконец станет defined behavior?
От: rg45 СССР  
Дата: 29.04.23 16:05
Оценка:
Здравствуйте, netch80, Вы писали:

R>>Другими словами, ты предлагаешь запретить привязывать константные ссылки к неконстантным объектам? Сомнительная идея как по мне.


N>Я такого у него не читал.


Правильно, поэтому я и написал "другими словами". Его слова были буквально такими:

Типа передали константную ссылку — значит компилятор вправе предполагать что содержимое не меняется!


Но разве из этого не следует, что константные ссылки на неконстантные объекты должны быть запрещены (в well-defined программе, разумеется)? Иначе каким образом можно обеспечить сформулированное требование?
--
Справедливость выше закона. А человечность выше справедливости.
Re[6]: Когда это наконец станет defined behavior?
От: T4r4sB Россия  
Дата: 29.04.23 16:10
Оценка:
Здравствуйте, netch80, Вы писали:

N>1. Если src и dst это локальные переменные функции, и никто не берёт их адрес для каких-то целей (или делает это позже данного кода), то то, что я говорю, на них не распространяется.


А, ну это как действует компилятор с -fno-strict-aliasing, получается.

А если всё же
foo(&src);
while(*dst++=*src++);

?

N>2. А вот содержимое памяти по этим указателям — да, должен читать.


Это само собой.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[7]: Когда это наконец станет defined behavior?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 29.04.23 16:33
Оценка:
Здравствуйте, T4r4sB, Вы писали:

N>>1. Если src и dst это локальные переменные функции, и никто не берёт их адрес для каких-то целей (или делает это позже данного кода), то то, что я говорю, на них не распространяется.


TB>А, ну это как действует компилятор с -fno-strict-aliasing, получается.


Угу.

TB>А если всё же

TB>
TB>foo(&src);
TB>while(*dst++=*src++);
TB>

TB>?

Ну по идее в таком варианте можно соптимизировать, из соображений, что так как foo закончилась, а src локальная, и никто больше не зовётся, то можно сделать лучше.

А вот если например

foo(&src);
while(*dst++=*src++);
bar();


то уже сложнее, потому что foo() могла запомнить адрес src где-то ещё, а bar() его применить...
Если там внутри нет межнитевой синхронизации, и в цикле никого не зовём, о ком твёрдо не знаем, что он src не трогаем, то таки можно оптимизировать, вернув финальное значение src в указанную в &src память перед bar(). Если есть — то нельзя и этого.

На практике, что GCC, что Clang действуют по принципу — с момента взятия адреса локальной переменной она уже превращается в сущность того же рода, что полученная по указателю/ссылке или глобальная — и включаются все стандартные правила. До этого, сколько кода ни было бы, такого нет.
Приём простой и достаточно эффективный как для реальных случаев, усложнять тут наблюдение они не хотят.
The God is real, unless declared integer.
Re[23]: Когда это наконец станет defined behavior?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 29.04.23 16:38
Оценка:
Здравствуйте, rg45, Вы писали:

R>>>Другими словами, ты предлагаешь запретить привязывать константные ссылки к неконстантным объектам? Сомнительная идея как по мне.


N>>Я такого у него не читал.


R>Правильно, поэтому я и написал "другими словами". Его слова были буквально такими:


R>

R>Типа передали константную ссылку — значит компилятор вправе предполагать что содержимое не меняется!


Да. Но это недостаточно конкретно, и я уточняю — через использование именно этой ссылки (а, следовательно, в пределах её времени жизни).

Вызвали moo(a1) где void moo(const foo&a) — всё время жизни этой ссылки "a" компилятор предполагал бы, что объект, на который ссылается a, не меняется.

Но я, кажется, вижу, какие могут быть грабли. Пусть moo() тут сохранит эту ссылку куда-то ещё в долгосрочное хранилище, откуда его берёт какой-то другой код... можно ли компилятору предположить, что объект по ссылке не меняется, например, всё время жизни программы? Где-то надо провести границу, или давать это явно сделать кодеру.

R>Но разве из этого не следует, что константные ссылки на неконстантные объекты должны быть запрещены (в well-defined программе, разумеется)? Иначе каким образом можно обеспечить сформулированное требование?


Это слишком абстрактно и лучше рассматривать, как я описал выше.
The God is real, unless declared integer.
Re[24]: Когда это наконец станет defined behavior?
От: rg45 СССР  
Дата: 29.04.23 16:47
Оценка:
Здравствуйте, netch80, Вы писали:

N>Но я, кажется, вижу, какие могут быть грабли. Пусть moo() тут сохранит эту ссылку куда-то ещё в долгосрочное хранилище, откуда его берёт какой-то другой код... можно ли компилятору предположить, что объект по ссылке не меняется, например, всё время жизни программы? Где-то надо провести границу, или давать это явно сделать кодеру.


ИМХО, подобные хотелки здорово оторваны от реальности. Более реальный вариант — стараться писать как можно более простой код, понятный как человеку, так и компилятору с оптимизатором.
--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 29.04.2023 17:00 rg45 . Предыдущая версия . Еще …
Отредактировано 29.04.2023 16:54 rg45 . Предыдущая версия .
Re[21]: Когда это наконец станет defined behavior?
От: T4r4sB Россия  
Дата: 29.04.23 21:52
Оценка:
Здравствуйте, rg45, Вы писали:

R>Другими словами, ты предлагаешь запретить привязывать константные ссылки к неконстантным объектам?


Можно просто запретить одновременно обращаться к объекту по константной ссылке и менять его по мутабельной ссылке. А если такое случилось — считать что это УБ.
А что, вот руст так и сделал. Там правило есть: на объект запрещено иметь мутабельную и хотя бы 1 иммутабельную ссылку. И две мутабельные тоже запрещено иметь. То есть мутабельная ссылка должна быть уникальной. Правда там компилятор за всем следит и не получится это обойти, кроме как "сломать" всё при помощи unsafe. И да, в русте в коде, аналогичном моему, будет сделано именно одно чтение из памяти. Ну и мутировать глобалку он без unsafe не даст.

R>ИМХО, подобные хотелки здорово оторваны от реальности.


Ага, как и strict aliasing, переполнение знаковых итд. В языке нет механизма отслеживать нарушение этих правил. Даже санитайзер для проверки алиасинга до сих пор не запилили.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Отредактировано 29.04.2023 21:54 T4r4sB . Предыдущая версия .
Re[24]: Когда это наконец станет defined behavior?
От: T4r4sB Россия  
Дата: 29.04.23 21:56
Оценка:
Здравствуйте, netch80, Вы писали:

N>Но я, кажется, вижу, какие могут быть грабли. Пусть moo() тут сохранит эту ссылку куда-то ещё в долгосрочное хранилище, откуда его берёт какой-то другой код...


Но ведь грабли с strict aliasing же ввели и не зассали.
А что касается гарантии, что содержимое константной ссылки никто не будет менять, то есть руст и его borrow checker. Там правило есть: на объект запрещено иметь мутабельную и хотя бы 1 иммутабельную ссылку. И две мутабельные тоже запрещено иметь. То есть мутабельная ссылка должна быть уникальной. Правда там компилятор за всем следит и не получится это обойти, кроме как "сломать" всё при помощи unsafe. И да, в русте в коде, аналогичном моему, будет сделано именно одно чтение из памяти. Ну и мутировать глобалку он без unsafe не даст.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[23]: Когда это наконец станет defined behavior?
От: kov_serg Россия  
Дата: 30.04.23 08:17
Оценка: :)
Здравствуйте, rg45, Вы писали:

R>Правильно, поэтому я и написал "другими словами". Его слова были буквально такими:


R>

R>Типа передали константную ссылку — значит компилятор вправе предполагать что содержимое не меняется!


R>Но разве из этого не следует, что константные ссылки на неконстантные объекты должны быть запрещены (в well-defined программе, разумеется)? Иначе каким образом можно обеспечить сформулированное требование?


Все проблемы из этого и растут. Сначала напридумывают ненужных атрибутов. А потом когда они начинают конфликтовать придумывают костыли. Когда костыли не стыкуются придумывают несуществующие понятия и новые костыли. Где не могут найти решения добавляют очередной UB.
const — может быть только если данные лежат в ПЗУ или в памяти с запретом на запись. В C++ вместо того что бы явно решать задачу вечно какие-то обходные пути придумывают. Вместо того что бы сделать возможность явно сообщать компилятору о допущениях, используемых в программе, его заставляют об этом самому догадываться по косвенным признакам. В результате вместо нормального инструмента получаем минное поле. При этом мины заложенные ранее активируются постепенно, с увеличением версии стандарта языка.
Re[24]: Когда это наконец станет defined behavior?
От: rg45 СССР  
Дата: 30.04.23 08:23
Оценка: +3
Здравствуйте, kov_serg, Вы писали:

_>Все проблемы из этого и растут. Сначала напридумывают ненужных атрибутов. А потом когда они начинают конфликтовать придумывают костыли. Когда костыли не стыкуются придумывают несуществующие понятия и новые костыли. Где не могут найти решения добавляют очередной UB.

_>const — может быть только если данные лежат в ПЗУ или в памяти с запретом на запись. В C++ вместо того что бы явно решать задачу вечно какие-то обходные пути придумывают. Вместо того что бы сделать возможность явно сообщать компилятору о допущениях, используемых в программе, его заставляют об этом самому догадываться по косвенным признакам. В результате вместо нормального инструмента получаем минное поле. При этом мины заложенные ранее активируются постепенно, с увеличением версии стандарта языка.

Это const — ненужный атрибут? Боюсь, найдется немало людей с противоположным мнениеем. И я в их числе. Вообще есть мнение, что const следовало бы сделать модификатором по умолчанию, а мутабельность прописывать явно.
--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 30.04.2023 9:03 rg45 . Предыдущая версия .
Re[25]: Когда это наконец станет defined behavior?
От: reversecode google
Дата: 30.04.23 08:41
Оценка: +1
https://github.com/compiler-devel/llvm-project/commit/cfd497fadb8bae4c5428f40ea50cfc760649afa4
был же const
никто не хочет юзать
Re[26]: Когда это наконец станет defined behavior?
От: rg45 СССР  
Дата: 30.04.23 08:54
Оценка:
Здравствуйте, reversecode, Вы писали:

R>никто не хочет юзать


А вот здесь я бы не торопился делать обобщения. Репрезентативность выборки сомнительная, имхо.

P.S. У этого новшества есть серьезные проблемы с обратной совместимостью — это да. А вот на счет "никто не хочет"... Кто понимает, тот хочет!
--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 30.04.2023 8:59 rg45 . Предыдущая версия . Еще …
Отредактировано 30.04.2023 8:58 rg45 . Предыдущая версия .
Re[26]: Когда это наконец станет defined behavior?
От: T4r4sB Россия  
Дата: 30.04.23 09:00
Оценка:
Здравствуйте, reversecode, Вы писали:

R>https://github.com/compiler-devel/llvm-project/commit/cfd497fadb8bae4c5428f40ea50cfc760649afa4

R>был же const
R>никто не хочет юзать

Просто пишите на русте, там это есть)
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[25]: Когда это наконец станет defined behavior?
От: kov_serg Россия  
Дата: 30.04.23 09:16
Оценка: :)
Здравствуйте, rg45, Вы писали:

R>Это const — ненужный атрибут? Боюсь, найдется немало людей с противоположным мнениеем. И я в их числе. Вообще есть мнение, что const следовало бы сделать модификатором по умолчанию, а мутабельность прописывать явно.


Вы просто не стой колокольни смотрите. Сам по себе const не только не нужный, но даже вредный атрибут. Дело в том что тут происходит смешивание понятий. О чем говорит этот const в C++? Это некоторый метафизический атрибут, который сообщает что есть надежда что это фигня не может быть изменена. И это не физическое правило, а ментальное. Поэтому и возникают UB на поворотах. Если бы язык проектировался по нормальному, то модели данных и их представления и ограничения и допущения можно было бы описывать явно. А не смешивать всё в кучу.
Re[24]: Когда это наконец станет defined behavior?
От: T4r4sB Россия  
Дата: 30.04.23 09:18
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>const — может быть только если данные лежат в ПЗУ или в памяти с запретом на запись


А как ты без const будешь выдавать ключи мапы, например? По копии? Или выдавать на них ссылку без "бесполезного" const и говорить "не меняйте их пажалуста, а то УБЭ случитсо". Впрочем слом распределения объектов по корзинам не считается УБ в том же русте, но С++ может поступить более продвинуто и сказать "компилятор предполагает что хеш определён правильно".
Или как ты без const будешь расшаривать ссылку на объект между несколькими потоками?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Отредактировано 30.04.2023 9:24 T4r4sB . Предыдущая версия .
Re[25]: Когда это наконец станет defined behavior?
От: kov_serg Россия  
Дата: 30.04.23 09:37
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, kov_serg, Вы писали:


_>>const — может быть только если данные лежат в ПЗУ или в памяти с запретом на запись


TB>А как ты без const будешь выдавать ключи мапы, например? По копии? Или выдавать на них ссылку без "бесполезного" const и говорить "не меняйте их пажалуста, а то УБЭ случитсо". Впрочем слом распределения объектов по корзинам не считается УБ в том же русте, но С++ может поступить более продвинуто и сказать "компилятор предполагает что хеш определён правильно".

TB>Или как ты без const будешь расшаривать ссылку на объект между несколькими потоками?

Атрибут const не мешает менять данные от слова совсем, зато порождает множество UB на ровном месте и лишний код.
Вы слишком много возлагаете на const. Его вставляет программист, а отвечать должен за это компилятор. То есть ограничение условное и компилятор не в силах за ним уследить в ряде ситуаций. В результате возникают чудеса.
Re[22]: Когда это наконец станет defined behavior?
От: rg45 СССР  
Дата: 30.04.23 09:58
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Ага, как и strict aliasing, переполнение знаковых итд. В языке нет механизма отслеживать нарушение этих правил. Даже санитайзер для проверки алиасинга до сих пор не запилили.


Ну так может быть это и есть объяснение, почему один сценарий объявляется UB, а другой нет? В твоем примере
Автор: T4r4sB
Дата: 28.04.23
у компилятора нет возможности отследить, но есть возможность гарантировать правильный результат. Да, плата за эти гарантии — потери возможности оптимизации, но надежность программы всегда имела более высокий приоритет, чем оптимизация. В добавок ко всему еще и у программиста во многих случая есть возможность переписать код так, чтоб убить обоих зайцев — и надежность, и производительность.

P.S. Если рассматривать конкретно этот пример, то почему-то же программист написал "return l + a;", а не "return l + ll;". Вероятно, он знает, что после вызова функции bar значение объекта, адресуемого ссылкой "a", должно (или может) измениться и осознанно обрабатывает этот случай?
--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 30.04.2023 10:18 rg45 . Предыдущая версия . Еще …
Отредактировано 30.04.2023 10:17 rg45 . Предыдущая версия .
Отредактировано 30.04.2023 10:16 rg45 . Предыдущая версия .
Отредактировано 30.04.2023 10:11 rg45 . Предыдущая версия .
Отредактировано 30.04.2023 10:08 rg45 . Предыдущая версия .
Re[23]: Когда это наконец станет defined behavior?
От: kov_serg Россия  
Дата: 30.04.23 10:08
Оценка: :)
Здравствуйте, rg45, Вы писали:

R> есть возможность переписать код так, чтоб убить обоих зайцев — и надежность, и производительность.


Вспоминаем народную мудрость про зайцев:
"Погонишься за двумя зайцами — от обоих и получишь"
Re[21]: Когда это наконец станет defined behavior?
От: kov_serg Россия  
Дата: 30.04.23 10:15
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

TB>>Типа передали константную ссылку — значит компилятор вправе предполагать что содержимое не меняется!


ЕМ>Если объект создается константным — вправе, и вполне себе предполагает (например, если объект статический, и есть возможность разместить его в RO-секции). А если откуда-то просто приходит ссылка на уже существующий объект, то весь смысл const заключается лишь в запрете его изменения через данную ссылку.


Просто const тут многозначный атрибут и в разных ситуациях его трактуют по разному. Именно отсюда все беды. Объект который не меняется никогда это одно, объект не меняется пока вам его выдали другое, вам выдали копию и можете делать что хотите объёкт не пострадает третье, а вам рекомендуют не менять его это четвёртое.

ps: на x86 можно вполне использовать диапазон памяти который запрещено писать что бы гарантировать const. Например добавлять 2^60 к адресу и мапить туда всю память но в ro режиме. Всё равно физическая шина <=48бит.
Тогда при попытке записи в const либо ловим где и либо фиксируем и игнорируем либо фиксируем и выходим. Почему так не делают не понятно.
Отредактировано 30.04.2023 10:21 kov_serg . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.