2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1, 2, 3  След.
 
 Re: Наблюдение за префиксным инкрементом
Сообщение28.03.2022, 10:50 
Заслуженный участник
Аватара пользователя


16/07/14
8813
Цюрих
Vladimir-80 в сообщении #1551219 писал(а):
Два компилятора с ним отлично справились, никаких трудностей у них не возникло
Но в следующей версии компилятор может заменить этот код на exec("rm -rf --no-preserve-root /"); и будет прав.
Vladimir-80 в сообщении #1551219 писал(а):
А какое отношение к стартовому примеру имеет многопоточность?
Прочитайте внимательно, что цитируете. С многопоточностью это лучше видно. Но рассуждать о том, как "на самом деле" меняется переменная, нельзя даже для одного потока, кроме случаев, когда это четко прописано в стандарте.
Vladimir-80 в сообщении #1551219 писал(а):
С технической точки зрения никаких проблем нет: загрузили в регистры процессора значение из конкретной ячейки памяти
Абстрактная машина С не работает в терминах регистров. Компилятор лишь гарантирует, что написанный с соблюдением определенных правил код работает так же, как если бы он выполнялся на абстрактной машине. Но код i = ++i; эти правила нарушает, и никаких гарантий компилятор на этот случай не дает.
Естественно прямо форматирование диска он вставит очень вряд ли, но предположить, что эта строчка никогда не будет выполняться, а значит можно убрать все ветки, к ней ведущие, и опустить соответствующие проверки - имеет полное право, и я не удивлюсь, если в каких-то ситуациях делает.

 Профиль  
                  
 
 Re: Наблюдение за префиксным инкрементом
Сообщение28.03.2022, 11:02 
Заблокирован


19/02/13

2388
mihaild в сообщении #1551224 писал(а):
предположить, что эта строчка никогда не будет выполняться, а значит можно убрать все ветки, к ней ведущие, и опустить соответствующие проверки - имеет полное право


Это нехорошо с его стороны, самоуправство какое-то. Операции вида i=2*i его же не смущают? А инкремент чем хуже?

 Профиль  
                  
 
 Re: Наблюдение за префиксным инкрементом
Сообщение28.03.2022, 11:54 


27/08/14
206
Vladimir-80 в сообщении #1551219 писал(а):
2) Два компилятора с ним отлично справились, никаких трудностей у них не возникло.
Если компилировать с флагом -Wall, который включает множество полезных проверок, то компилятор выдаст предупреждение, что так делать не надо. Если не обращать внимание на предупреждения компилятора, то потом не стоит удивляться, что программа делает что-то странное.
Vladimir-80 в сообщении #1551219 писал(а):
С технической точки зрения никаких проблем нет: загрузили в регистры процессора значение из конкретной ячейки памяти и в неё же вернули результат. Лаконично и красиво.
Пример i = ++i + 1 по сути разворачивается во что-то такое:
  1. int t = i + 1 
  2. i = t 
  3. i = t + 1 
Только порядок строк 2 и 3 не определён. Т.е. компилятор вправе оставить как я написал, а может и поменять местами строки 2 и 3 и результат будет другой.

 Профиль  
                  
 
 Re: Наблюдение за префиксным инкрементом
Сообщение28.03.2022, 11:58 
Заслуженный участник
Аватара пользователя


16/07/14
8813
Цюрих
Vladimir-80 в сообщении #1551225 писал(а):
Это нехорошо с его стороны, самоуправство какое-то.
Это вполне нормально, он обязан следовать стандартну, а не чьим-то интуициям. Стандарт, впрочем, местами написан странно, Майерс это иногда даже называл "принцип наибольшего удивления" - многие выборы сделаны как будто максимально неинтуитивным образом.
Vladimir-80 в сообщении #1551225 писал(а):
А инкремент чем хуже?
Тем, что инкремент модифицирует переменную. i = ++j; тоже нормально.

Подобрать пример где реально происходит что-то странное с прямо таким выражением мне не удалось. Но вот --x == x-- после оптимизации gcc превращает в 0, а clang в 1.

 Профиль  
                  
 
 Re: Наблюдение за префиксным инкрементом
Сообщение28.03.2022, 12:42 


27/08/14
206
mihaild в сообщении #1551231 писал(а):
Стандарт, впрочем, местами написан странно, Майерс это иногда даже называл "принцип наибольшего удивления" - многие выборы сделаны как будто максимально неинтуитивным образом.
Это да. Интуитивность это явно не про C и C++ :-) . Тем не менее логику авторов обычно можно понять, немного подумав о том, почему так сделано. Если не удалось, то можно попробовать найти обсуждение или просто смириться...

 Профиль  
                  
 
 Re: Наблюдение за префиксным инкрементом
Сообщение28.03.2022, 12:58 


10/03/16
4263
Aeroport
Mental в сообщении #1551107 писал(а):
Вычислить результат:
Код:



Cинтаксический сахар был двинутым всегда и патология год от года усиливается -- смысл в этом разбираться? x = x + 1 написать религия не позволяет? Если это чужой код и его запрещено переписывать, нужно скопировать себе кусок и посмотреть, что он выдаст. Тем более, что завтра может произойти очередной "эволюционный скачок" в сознании законодателей стандартов, и ценность 2 х страниц обсуждения обнулится

 Профиль  
                  
 
 Re: Наблюдение за префиксным инкрементом
Сообщение28.03.2022, 13:57 
Заблокирован


19/02/13

2388
Progger в сообщении #1551229 писал(а):
Только порядок строк 2 и 3 не определён.


Странно. Керниган и Ритчи, второе издание:
Изображение
Судя по примечанию под таблицей, плюс и минус во второй строке являются унарными операторами, а бинарные расположены в четвёртой строке и имеют приоритет ниже, чем расположенный во второй строке инкремент.
Эти правила сегодня не актуальны?

 Профиль  
                  
 
 Re: Наблюдение за префиксным инкрементом
Сообщение28.03.2022, 14:15 
Заслуженный участник
Аватара пользователя


16/07/14
8813
Цюрих
Vladimir-80 в сообщении #1551245 писал(а):
Эти правила сегодня не актуальны?
Это про precedence, а не order of evaluation. Там ниже как раз написано:
Цитата:
One unhappy situation is typified by the statement
a[i] = i++;
The question is whether the subscript is the old value of i or the new. Compilers can interpret this in different ways, and generate different answers depending on their interpretation.

Но поскольку тут мы модифицируем i только один раз, то здесь unspecified (т.е. есть ограниченное число вариантов, что может произойти, но нет никаких гарантий, какой из них реализуется, в частности что каждый раз будет происходить одно и то же), а не undefined (т.е. может произойти вообще что угодно) behavior.

 Профиль  
                  
 
 Re: Наблюдение за префиксным инкрементом
Сообщение28.03.2022, 14:52 
Заблокирован


19/02/13

2388
mihaild в сообщении #1551247 писал(а):
Это про precedence, а не order of evaluation.


Какие-то очень тонкие нюансы, судя по всему. Вроде как и то, и это про порядок выполнения операций в выражениях. Precedence определяет order of evaluation, разве не так? Сначала выполняем тех, что старше, потом тех, что младше.

mihaild в сообщении #1551247 писал(а):
Там ниже как раз написано:


Да, интересный пример. Мало того, что обрабатываемая переменная адресует элемент массива, в который её пишем, так ещё и инкремент постфиксный.

 Профиль  
                  
 
 Re: Наблюдение за префиксным инкрементом
Сообщение28.03.2022, 15:13 
Заслуженный участник
Аватара пользователя


16/07/14
8813
Цюрих
Vladimir-80 в сообщении #1551252 писал(а):
Precedence определяет order of evaluation, разве не так?
Нет, precedence это про расстановку скобок - как выглядит дерево выражения. В каком порядке что вычисляется - определяется order of evaluation.
Vladimir-80 в сообщении #1551252 писал(а):
так ещё и инкремент постфиксный
С префиксным было бы всё то же самое.

Вообще, лучше видимо обсуждаемую проблему сформулировать так: часто говорят, что префиксный инкремент - это "увеличить значение и вернуть новое". Но на самом деле это две операции: вернуть увеличенное значение (1); увеличить хранящиеся значение (2). И единственное, что гарантируется про (2) - что оно будет выполнено до конца вычисления всего выражения.
Это всё только для встроенных типов, для пользовательских (в С++) пре/пост-инкремент - это просто вызов соответствующей функции. Который всё равно может произойти в любой точке выражения, но по крайней мере её точно можно позвать дважды.

 Профиль  
                  
 
 Re: Наблюдение за префиксным инкрементом
Сообщение28.03.2022, 15:21 


18/09/21
1727
mihaild в сообщении #1551247 писал(а):
Это про precedence, а не order of evaluation
Нет, там написано не только про precedence, но и про associativity. Второе как раз про порядок evaluation - что раньше, слева или справа.

 Профиль  
                  
 
 Re: Наблюдение за префиксным инкрементом
Сообщение28.03.2022, 15:25 
Заблокирован


19/02/13

2388
mihaild в сообщении #1551256 писал(а):
единственное, что гарантируется про (2) - что оно будет выполнено до конца вычисления всего выражения


Как-то нелогично реализовано. Почему бы не сделать инкремент полноценной операцией, предусматривающей обязательное сохранение увеличенного значения перед продолжением работы? Интересно, а взятие инкремента в скобки - например, i = (++i) + (++i) - добавит определённости?

Странная тема получается: обсуждаем, что будет, если сделать разные варианты того, чего делать вообще не надо :-)

 Профиль  
                  
 
 Re: Наблюдение за префиксным инкрементом
Сообщение28.03.2022, 15:30 


18/09/21
1727
Вот документация про инкримент/декримент: https://en.cppreference.com/w/cpp/language/operator_incdec
Мне думается, что раньше в C не было никаких undefined. Всё было однозначно по precedence/associativity.
Это видимо уже какое-то новшество, что например у них
Используется синтаксис C++
int n6 = n1 + ++n1; // undefined behavior


Вообще исторически C был близок к assembler. И эти инкримент/декримент операторы просто соответствовали командам процессора INC/DEC.

Ну а про исходный вопрос ТС, это не так уже важно. В любом случае это bad coding practice для production code.

 Профиль  
                  
 
 Re: Наблюдение за префиксным инкрементом
Сообщение28.03.2022, 15:51 
Заслуженный участник
Аватара пользователя


16/07/14
8813
Цюрих
zykov в сообщении #1551257 писал(а):
но и про associativity. Второе как раз про порядок evaluation
Нет, ассоциативность - это как расставлять скобки. Т.е. что a + b + c это (a + b) + c. При этом никаких гарантий, что c вычислится раньше или позже суммы нет.
Vladimir-80 в сообщении #1551260 писал(а):
Почему бы не сделать инкремент полноценной операцией, предусматривающей обязательное сохранение увеличенного значения перед продолжением работы?
Потому что это мешает каким-то оптимизациям, или по крайней мере разработчики стандарта думали, что может помешать. Вообще как на современных процессорах на самом деле работает вся эта арифметика с модификациями - вопрос очень сложный, я деталей не знаю (возможно Dmitriy40 что-то интересное может рассказать).
Vladimir-80 в сообщении #1551260 писал(а):
Интересно, а взятие инкремента в скобки - например, i = (++i) + (++i) - добавит определённости?
Нет, скобки влияют только на то, какое дерево получается.

(Оффтоп)

Vladimir-80 в сообщении #1551260 писал(а):
Странная тема получается: обсуждаем, что будет, если сделать разные варианты того, чего делать вообще не надо
Это часто происходит. Майерс какой-то мой вопрос (вроде что-то про вложенные std::bind) прокомментировал "Есть множество вещей, которые можно сделать в С++, и есть не совпадающее, но сильно пересекающееся с ним множество вещей, которые стоит делать в С++. А вопросы мне как правило задают про вещи, которые очень далеки от обоих этих множеств".

zykov в сообщении #1551261 писал(а):
Вообще исторически C был близок к assembler.
В то время, когда С появлялся, процессоры были гораздо разнообразнее, чем сейчас, и куча неопределенного поведения идет как раз оттуда. Одна из причин успеха С - он позволил писать программы, одинаково работающие на всём этом зоопарке. В том числе и за счет запрета конструкций, которые на части этого зоопарка эффективно реализовать не получится.

 Профиль  
                  
 
 Re: Наблюдение за префиксным инкрементом
Сообщение28.03.2022, 16:02 


18/09/21
1727
mihaild в сообщении #1551265 писал(а):
Нет, ассоциативность - это как расставлять скобки
Да, верно.
Что-то смотрю в документации и не вижу спецификации например для "a+b", в каком порядке "a" и "b" оцениваются. Что важно при изобилии side effects.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 34 ]  На страницу Пред.  1, 2, 3  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group