Дьюхарст про такой вызов функции fun(i, i++); пишет что это непереносимо. А разве это не undefined ? Значение читается (не для определения нового значения) и меняется между двумя точками следования
Re: C++ gotchas
От:
Аноним
Дата:
22.09.03 13:25
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Дьюхарст про такой вызов функции fun(i, i++); пишет что это непереносимо. А разве это не undefined ? Значение читается (не для определения нового значения) и меняется между двумя точками следования
Ну да, undefined.
P.S. Так он еще считает, что приоритет у запятой выше, чем у присваивания.
Re[2]: C++ gotchas
От:
Аноним
Дата:
22.09.03 13:29
Оценка:
А>P.S. Так он еще считает, что приоритет у запятой выше, чем у присваивания.
Здорово. До такого я еще не дочитал. Так в чем же тогда реальные готчи? В ошибках автора?
Здравствуйте, Аноним, Вы писали:
А>Дьюхарст про такой вызов функции fun(i, i++); пишет что это непереносимо. А разве это не undefined ? Значение читается (не для определения нового значения) и меняется между двумя точками следования
Вариант первый:
1. Оцениваем второй аргумент
2. Инкрементируем второй аргумент
3. Оцениваем первый аргумент
4. Вызываем fun
Вариант второй
1. Оцеиваем втоорой аргумент
2. Оцениваем первый аргумент
3. Вызываем fun
4. Инкрементируем i
....
Вариант N
Главное, чтобы аргументы были вычислены до вызова функции, а каком порядке — неважно. У Саттера про это хорошо написано.
Re[2]: C++ gotchas
От:
Аноним
Дата:
22.09.03 13:45
Оценка:
Мне так не кажется. Данный вызов похож на j = i + i++;
Re[2]: C++ gotchas
От:
Аноним
Дата:
22.09.03 13:50
Оценка:
Здравствуйте, Anton V. Kolotaev, Вы писали:
А>>Дьюхарст про такой вызов функции fun(i, i++); пишет что это непереносимо. А разве это не undefined ? Значение читается (не для определения нового значения) и меняется между двумя точками следования
Что это Вы называете "оцениванием"? Получение значения?
AVK>Вариант первый: AVK>1. Оцениваем второй аргумент AVK>2. Инкрементируем второй аргумент AVK>3. Оцениваем первый аргумент
Вот здесь и падаем: чтение после записи без промежуточных точек следования.
AVK>4. Вызываем fun
AVK>Вариант второй AVK>1. Оцеиваем втоорой аргумент AVK>2. Оцениваем первый аргумент AVK>3. Вызываем fun AVK>4. Инкрементируем i
А вот так нельзя: перед входом в fun — точка следования, к ней никремент уже должен быть произведен.
Здравствуйте, Аноним, Вы писали:
А>Дьюхарст про такой вызов функции fun(i, i++); пишет что это непереносимо. А разве это не undefined ? Значение читается (не для определения нового значения) и меняется между двумя точками следования
А>>Дьюхарст про такой вызов функции fun(i, i++); пишет что это непереносимо. А разве это не undefined ? Значение читается (не для определения нового значения) и меняется между двумя точками следования
А>Ну да, undefined.
Непереносимость и undefined — это одно и то же. Если в стандарте про что-то написано undefined — то это не значит, что при нескольких прогонах программы результат будет разный. Это значит, что на разных платформах поведение (behaviour) программы будет разным (т.е. с точки зрения стандарта, undefined). Но с точки зрения компилятора оно вполне однозначно.
Обращение по нулевому адресу стандарт также считает undefined behaviour, потому что на одних процессорах произойдет нарушение защиты памяти, а на других может не быть такой аппаратуры и поэтому ошибки не будет.
А>P.S. Так он еще считает, что приоритет у запятой выше, чем у присваивания.
У операции "запятая" приоритет действительно выше, чем у присваивания. Только надо различать, где операция "запятая", а где разделение параметров функции.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Anton V. Kolotaev, Вы писали:
А>>>Дьюхарст про такой вызов функции fun(i, i++); пишет что это непереносимо. А разве это не undefined ? Значение читается (не для определения нового значения) и меняется между двумя точками следования
А>Что это Вы называете "оцениванием"? Получение значения?
Видимо, имеется в виду слово evaluation, у которого первое значение — как раз "оценка", хотя, на мой взгляд, здесь нужно пользоваться вторым значением — "вычисление".
AVK>>Вариант первый: AVK>>1. Оцениваем второй аргумент AVK>>2. Инкрементируем второй аргумент AVK>>3. Оцениваем первый аргумент
А>Вот здесь и падаем: чтение после записи без промежуточных точек следования.
Все здесь нормально с точками следования! Не валите все undefined в одну кучу :)
Суть этого примера в том, что Стандартом не определен порядок вычисления аргументов функции, но каждый аргумент должен быть вычислен целиком со всеми своими побочными эффектами до тог, как начнет вычисляться следующий или начнет вычисляться функция.
так что здесь только 2 сценария: (допустим, что i изначально равна 1):
либо
вычисляем первый аргумент: 1, i = 1
вычисляем второй аргумент: 1, i = 2
вычисляем функцию fun(1,1)
либо
вычисляем второй аргумент: 1, i = 2
вычисляем первый аргумент: 2, i = 2
вычисляем функцию fun(1,2)
вот в этом и разница. И падать тут нечему.
Сейчас под рукой Стандарта нет, но, насколько я помню, такое поведение unspecified, но не undefined.
You will always get what you always got
If you always do what you always did
Re[3]: C++ gotchas
От:
Аноним
Дата:
23.09.03 07:42
Оценка:
Здравствуйте, SWW, Вы писали:
А>>P.S. Так он еще считает, что приоритет у запятой выше, чем у присваивания.
SWW>У операции "запятая" приоритет действительно выше, чем у присваивания. Только надо различать, где операция "запятая", а где разделение параметров функции.
Откройте любой учебник по C/C++ на таблице приоритетов.
Re[4]: C++ gotchas
От:
Аноним
Дата:
23.09.03 07:45
Оценка:
Здравствуйте, jazzer, Вы писали:
J>Суть этого примера в том, что Стандартом не определен порядок вычисления аргументов функции, но каждый аргумент должен быть вычислен целиком со всеми своими побочными эффектами до тог, как начнет вычисляться следующий
Из чего Вы это заключили?
J>Сейчас под рукой Стандарта нет, но, насколько я помню, такое поведение unspecified, но не undefined.
Ну да, опечатка там есть, но не в нормативной части.
Re[2]: C++ gotchas
От:
Аноним
Дата:
23.09.03 07:45
Оценка:
Здравствуйте, fin, Вы писали:
А>>Дьюхарст про такой вызов функции fun(i, i++); пишет что это непереносимо. А разве это не undefined ? Значение читается (не для определения нового значения) и меняется между двумя точками следования
fin>попробуй
fin>
Здравствуйте, SWW, Вы писали:
S> Непереносимость и undefined — это одно и то же.
Вовсе нет. Т.е. любая программа, выполнение которой приводит к undefined behavior, непереносима (если
подразумевается некоторая "универсальная" переносимость), но не любая непереносимая программа (в том
же смысле) содержит undefined behavior. В частности, стандарт различает как минимум три вида подобных
"поведений": undefined, unspecified и implementation defined. Все три приводят к непереносимости,
но только одно из них — undefined. Подробнее: http://www.rsdn.ru/forum/Message.aspx?mid=215574
S> Если в стандарте про что-то написано undefined — то это не значит, что при нескольких S> прогонах программы результат будет разный.
Вполне возможно, что результат выполнения программы, приводящей к undefined behavior, будет различаться
от запуска к запуску. Определение undefined behavior (1.3.12) вполне допускает подобное; более того,
это вполне распространенный вариант.
S> У операции "запятая" приоритет действительно выше, чем у присваивания.
Это утверждение не является верным (см. грамматику в 5.18). В частности, выводом следующей программы:
#include <iostream>
int main()
{
int i;
i = 10, 5;
std::cout << i << std::endl;
}
является:
10
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, jazzer, Вы писали:
А>>>> fun(i, i++)
AVK>>> Вариант первый: AVK>>> 1. Оцениваем второй аргумент AVK>>> 2. Инкрементируем второй аргумент AVK>>> 3. Оцениваем первый аргумент
А>> Вот здесь и падаем: чтение после записи без промежуточных точек следования.
j> Все здесь нормально с точками следования! Не валите все undefined в одну кучу
Не "нормально": стандарт не разрешает подобный доступ к предыдущему значению в случае
модификации без промежуточной точки следования (5/4):
Between the previous and next sequence point a scalar object shall have its stored value modified
at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only
to determine the value to be stored. The requirements of this paragraph shall be met for each
allowable ordering of the subexpressions of a full expression; otherwise the behavior is undefined.
j> Суть этого примера в том, что Стандартом не определен порядок вычисления аргументов функции,
Верно.
j> но каждый аргумент должен быть вычислен целиком со всеми своими побочными эффектами до тог, как j> начнет вычисляться следующий
А вот такого требования в стандарте нет.
j> или начнет вычисляться функция.
Это снова верно.
j> Сейчас под рукой Стандарта нет, но, насколько я помню, такое поведение unspecified, но не undefined.
Именно undefined.
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
SWW>>У операции "запятая" приоритет действительно выше, чем у присваивания. Только надо различать, где операция "запятая", а где разделение параметров функции.
А>Откройте любой учебник по C/C++ на таблице приоритетов.
Пардон, зарапортовался. Конечно же у запятой приоритет самый низкий.
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, Аноним, Вы писали:
А>>Точка следования только после того, как вычислены все аргументы.
J>Ну, там она точно есть, а вот между аргументами... J>Доберусь до стандарта, уточню. Хотя, наверное, вы правы, это более по духу С++...
Да, все правильно, между вычислением аргументов точки следования нет.