Здравствуйте, Vain, Вы писали:
V>Здравствуйте, jyuyjiyuijyu, Вы писали:
J>> не может вычислятся часть правого подвыражения пока не вычислено все левое выражение J>>со всеми побочными эффектами и к запятой это тоже относится J>>иначе весь код который сейчас работает просто бы рухнул V>На другом компиляторе он и рухнет если так и дальше будете писать.
J>>язык гарантирует вычисление всего левого выражения перед вычислением правого J>>иначе например вы хотите сказать что этот код тоже не верный J>>n++ != first_magic++ && first_magic != read_second_magic(n) ??? V>В данном случае неперегруженный оператор "&&" требует чтобы к моменту его вычисления левый операнд уже был вычислен, т.к. этот оператор вычисляет операнды в предопределённом порядке (в отличии, к примеру, от бинарного оператора "&"). А дальнейшее поведение думаю будет зависить от "аггрессивности" оптимизатора.
J>>если рассуждать как вы то тут вообще все плохо J>>или вот J>>int k = 1, u = 1, n = 1; J>>k = n++ + u++, n = k++ + u++, u = n++ + k++; J>>printf("%d %d %d\n", k, u, n); J>>output: 4 7 5 J>>это вообще смертельно было бы однако работает как и ожидается V>Не вижу противоречия.
покажите код который будет неправильно работать с предварительным тестом если можете
#define is_digit(x) (def(x),(acc(x) >= '0' && acc(x) <= '9') ? true : false)
тут нет ub никак кроме как присвоить (def) а потом прочитать (acc) он этот
код интерпретировать не сможет
просто покажите реальный код неправильно работающий все и ненадо будет спорить
или покажите где этот код не как ожидается будет работать
#define is_digit(x) (def(x),(acc(x) >= '0' && acc(x) <= '9') ? true : false)
Здравствуйте, jyuyjiyuijyu, Вы писали:
V>>Не вижу противоречия. J>покажите код который будет неправильно работать с предварительным тестом если можете
Я такой код не собираю, чтобы показывать, скорее наоборот, пытаюсь избавиться от него всеми методами.
J>#define is_digit(x) (def(x),(acc(x) >= '0' && acc(x) <= '9') ? true : false) J>тут нет ub никак кроме как присвоить (def) а потом прочитать (acc) он этот J>код интерпретировать не сможет
Думаю нету гарантии что def(x) вычислится до acc(x), который сам является частью другого подвыражения.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, Vain, Вы писали:
V>Здравствуйте, jyuyjiyuijyu, Вы писали:
V>>>Не вижу противоречия. J>>покажите код который будет неправильно работать с предварительным тестом если можете V>Я такой код не собираю, чтобы показывать, скорее наоборот, пытаюсь избавиться от него всеми методами.
J>>#define is_digit(x) (def(x),(acc(x) >= '0' && acc(x) <= '9') ? true : false) J>>тут нет ub никак кроме как присвоить (def) а потом прочитать (acc) он этот J>>код интерпретировать не сможет V>Думаю нету гарантии что def(x) вычислится до acc(x), который сам является частью другого подвыражения.
ладно останемся каждый при своем мнении в любом случае спасибо за беседу
приятно было пообщаться
V>Порядок определён между нодами с общим родителем, не глубже. Другими словами порядок вычисления листьев может быть таким: 3->1->4->2. Поэтому при вычислении подвыражений результат вычисления самих выражений может измениться из-за порядка между подвыражениями. А сами операторы определяют (если определяют, к примеру, к запятой это не относится) порядок только между своими операндами, но не глубже.
Тогда как гарантируется то, после оператора "&&" все сайд-эффекты будут учтены, если первым выполнится [3], а не [1] ?
Стандарт говорит:
"Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false."
Как может быть порядок вычисления 3-1-4-2 ?
Здравствуйте, Valen, Вы писали:
V>Тогда как гарантируется то, после оператора "&&" все сайд-эффекты будут учтены, если первым выполнится [3], а не [1] ? V>Стандарт говорит: V>"Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false." V>Как может быть порядок вычисления 3-1-4-2 ?
Ну с операторами && и || всё строго должно быть, иначе бы были интересные побочные эффекты.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, Vain, Вы писали:
V>Здравствуйте, Valen, Вы писали:
V>>Тогда как гарантируется то, после оператора "&&" все сайд-эффекты будут учтены, если первым выполнится [3], а не [1] ? V>>Стандарт говорит: V>>"Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false." V>>Как может быть порядок вычисления 3-1-4-2 ? V>Ну с операторами && и || всё строго должно быть, иначе бы были интересные побочные эффекты.
теперь вам осталось оюяснить чем && || отличаются от , ?: в плане
порядка вычисления выражений я понял так что для вас в && || ничего не может
считатся справа пока не вычислено все выражение слева но почему то для
оператора , (запятая) у вас такой гарантии нет это лично для меня удивительно
Здравствуйте, jyuyjiyuijyu, Вы писали:
V>>>Тогда как гарантируется то, после оператора "&&" все сайд-эффекты будут учтены, если первым выполнится [3], а не [1] ? V>>>Стандарт говорит: V>>>"Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false." V>>>Как может быть порядок вычисления 3-1-4-2 ? V>>Ну с операторами && и || всё строго должно быть, иначе бы были интересные побочные эффекты. J>теперь вам осталось оюяснить чем && || отличаются от , ?: в плане J>порядка вычисления выражений я понял так что для вас в && || ничего не может J>считатся справа пока не вычислено все выражение слева но почему то для J>оператора , (запятая) у вас такой гарантии нет это лично для меня удивительно
Ну так "left-to-right" неоднозначно определяет как можно раскрывать операнды операторов, поэтому если для && || это ещё может быть понятно, то для запятой — не факт.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, Vain, Вы писали:
V>Здравствуйте, jyuyjiyuijyu, Вы писали:
V>>>>Тогда как гарантируется то, после оператора "&&" все сайд-эффекты будут учтены, если первым выполнится [3], а не [1] ? V>>>>Стандарт говорит: V>>>>"Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false." V>>>>Как может быть порядок вычисления 3-1-4-2 ? V>>>Ну с операторами && и || всё строго должно быть, иначе бы были интересные побочные эффекты. J>>теперь вам осталось оюяснить чем && || отличаются от , ?: в плане J>>порядка вычисления выражений я понял так что для вас в && || ничего не может J>>считатся справа пока не вычислено все выражение слева но почему то для J>>оператора , (запятая) у вас такой гарантии нет это лично для меня удивительно V>Ну так "left-to-right" неоднозначно определяет как можно раскрывать операнды операторов, поэтому если для && || это ещё может быть понятно, то для запятой — не факт.
а как же
A7.18. Оператор запятая
выражение:
выражение-присваивания
выражение , выражение-присваивания
Два выражения, разделенные запятой, вычисляются слева направо, и значение левого выражения отбрасывается. Тип и значение результата совпадают с типом и значением правого операнда. Вычисление всех побочных эффектов левого операнда завершается перед началом вычисления правого операнда. В контексте, в котором запятая имеет специальное значение, например в списках аргументов функций (A7.3.2) или в списках инициализаторов (A8.7) (здесь в качестве синтаксических единиц фигурируют выражения присваивания), оператор запятая может появиться только в группирующих скобках. Например, в
f(a, (t=3, t+2), c)
три аргумента, из которых второй имеет значение 5.
разве это не гарантирует порядок вычисления ? вроде тут ясно сказано что ничего справа не будет вычиислятся пока все выражение слева со всеми побочными эффекитами не вычислится
Здравствуйте, Vain, Вы писали:
V>Здравствуйте, jyuyjiyuijyu, Вы писали:
V>>>>Тогда как гарантируется то, после оператора "&&" все сайд-эффекты будут учтены, если первым выполнится [3], а не [1] ? V>>>>Стандарт говорит: V>>>>"Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false." V>>>>Как может быть порядок вычисления 3-1-4-2 ? V>>>Ну с операторами && и || всё строго должно быть, иначе бы были интересные побочные эффекты. J>>теперь вам осталось оюяснить чем && || отличаются от , ?: в плане J>>порядка вычисления выражений я понял так что для вас в && || ничего не может J>>считатся справа пока не вычислено все выражение слева но почему то для J>>оператора , (запятая) у вас такой гарантии нет это лично для меня удивительно V>Ну так "left-to-right" неоднозначно определяет как можно раскрывать операнды операторов, поэтому если для && || это ещё может быть понятно, то для запятой — не факт.
вот к примру что говорится про &&
A7.14. Оператор логического И
логическое-И-выражение:
ИЛИ-выражение
логическое-И-выражение && ИЛИ-выражение
Операторы && выполняются слева направо. Оператор && выдает 1, если оба операнда не равны нулю, и 0 в противном случае. В отличие от &, && гарантирует, что вычисления будут проводиться слева направо: вычисляется первый операнд со всеми побочными эффектами; если он равен 0, то значение выражения есть 0. В противном случае вычисляется правый операнд, и, если он ранен 0, то значение выражения есть 0, в противном случае оно равно 1.
Операнды могут принадлежать к разным типам, но при этом каждый из них должен иметь либо арифметический тип, либо быть указателем. Тип результата — int.
помоему одно и тоже говорится про порядок вычисления между && и ,
Здравствуйте, jyuyjiyuijyu, Вы писали:
V>>>>>Тогда как гарантируется то, после оператора "&&" все сайд-эффекты будут учтены, если первым выполнится [3], а не [1] ? V>>>>>Стандарт говорит: V>>>>>"Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false." V>>>>>Как может быть порядок вычисления 3-1-4-2 ? V>>>>Ну с операторами && и || всё строго должно быть, иначе бы были интересные побочные эффекты. J>>>теперь вам осталось оюяснить чем && || отличаются от , ?: в плане J>>>порядка вычисления выражений я понял так что для вас в && || ничего не может J>>>считатся справа пока не вычислено все выражение слева но почему то для J>>>оператора , (запятая) у вас такой гарантии нет это лично для меня удивительно V>>Ну так "left-to-right" неоднозначно определяет как можно раскрывать операнды операторов, поэтому если для && || это ещё может быть понятно, то для запятой — не факт. J>а как же J>
J>A7.18. Оператор запятая
J>выражение:
J> выражение-присваивания
J> выражение , выражение-присваивания
J>Два выражения, разделенные запятой, вычисляются слева направо, и значение левого выражения отбрасывается. Тип и значение результата совпадают с типом и значением правого операнда. Вычисление всех побочных эффектов левого операнда завершается перед началом вычисления правого операнда. В контексте, в котором запятая имеет специальное значение, например в списках аргументов функций (A7.3.2) или в списках инициализаторов (A8.7) (здесь в качестве синтаксических единиц фигурируют выражения присваивания), оператор запятая может появиться только в группирующих скобках. Например, в
J>f(a, (t=3, t+2), c)
J>три аргумента, из которых второй имеет значение 5.
J>разве это не гарантирует порядок вычисления ? вроде тут ясно сказано что ничего справа не будет вычиислятся пока все выражение слева со всеми побочными эффекитами не вычислится
А там вроде сказано что за side effect'ы:
7. Accessing an object designated by a volatile lvalue (3.10), modifying an object, calling a library I/O
function, or calling a function that does any of those operations are all side effects, which are changes in the
state of the execution environment.
В примере было чтение не volatile переменной и что теперь? Как себя компилятор должен повести?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, Vain, Вы писали:
V>Здравствуйте, jyuyjiyuijyu, Вы писали:
V>>>>>>Тогда как гарантируется то, после оператора "&&" все сайд-эффекты будут учтены, если первым выполнится [3], а не [1] ? V>>>>>>Стандарт говорит: V>>>>>>"Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false." V>>>>>>Как может быть порядок вычисления 3-1-4-2 ? V>>>>>Ну с операторами && и || всё строго должно быть, иначе бы были интересные побочные эффекты. J>>>>теперь вам осталось оюяснить чем && || отличаются от , ?: в плане J>>>>порядка вычисления выражений я понял так что для вас в && || ничего не может J>>>>считатся справа пока не вычислено все выражение слева но почему то для J>>>>оператора , (запятая) у вас такой гарантии нет это лично для меня удивительно V>>>Ну так "left-to-right" неоднозначно определяет как можно раскрывать операнды операторов, поэтому если для && || это ещё может быть понятно, то для запятой — не факт. J>>а как же J>>
J>>A7.18. Оператор запятая
J>>выражение:
J>> выражение-присваивания
J>> выражение , выражение-присваивания
J>>Два выражения, разделенные запятой, вычисляются слева направо, и значение левого выражения отбрасывается. Тип и значение результата совпадают с типом и значением правого операнда. Вычисление всех побочных эффектов левого операнда завершается перед началом вычисления правого операнда. В контексте, в котором запятая имеет специальное значение, например в списках аргументов функций (A7.3.2) или в списках инициализаторов (A8.7) (здесь в качестве синтаксических единиц фигурируют выражения присваивания), оператор запятая может появиться только в группирующих скобках. Например, в
J>>f(a, (t=3, t+2), c)
J>>три аргумента, из которых второй имеет значение 5.
J>>разве это не гарантирует порядок вычисления ? вроде тут ясно сказано что ничего справа не будет вычиислятся пока все выражение слева со всеми побочными эффекитами не вычислится V>А там вроде сказано что за side effect'ы: V>
V>7. Accessing an object designated by a volatile lvalue (3.10), modifying an object, calling a library I/O
V>function, or calling a function that does any of those operations are all side effects, which are changes in the
V>state of the execution environment.
V>В примере было чтение не volatile переменной и что теперь? Как себя компилятор должен повести?
тоесть отличаются побочные эффекты для
&& || и для , ?: которые вляют на порядок вычисления ?
а что тогда означает modifying an object разве не изменение переменной
в том числе инкремент присваивание и прочее ?
это было бы багом гарантировать изменение только volatile переменной
а простой нет еще каким багом и слава разработчикам компилятора их
компиляторы так не делают
а вот на того кто придумал такое безумие интересно было бы посмотреть
но самое главное нет причин для такого безумства в чем смысл гарантировать
изменение только volatile переменной для опретора , (запятая) а для
&& (логическое и) гарантировать изменение любой переменной это же
чистой воды бред сумашедшего
а вот интересно как в жизни например MSVC/C++ всегда выполняет все
побочные эффекты в операторе , (запятая) перед тем как вычислять
выражение справа а GCC интересно выполняет ? кто нибудь может проверить
на всех уровнях оптимизации ?
все таки стандарт C намного проще там четко сказано любые побочные эффекты
(про операторы было из С) а в плюсах какие то страсти мордасти создается
ощущение что собрались извращенцы и пишут стандарт C++ для таких же извращенцев
как они сами
jyuyjiyuijyu:
J>а вот интересно как в жизни например MSVC/C++ всегда выполняет все J>побочные эффекты в операторе , (запятая) перед тем как вычислять J>выражение справа а GCC интересно выполняет ? кто нибудь может проверить J>на всех уровнях оптимизации ?
Это бессмысленные вопросы. Компилятор должен обеспечить допустимое наблюдаемое поведение — т.е. то, которое могло бы получиться при выполнении программы на абстрактной машине. Для этого компилятору нет необходимости в точности воспроизводить исходный алгоритм, заданный программистом. Например, вычисление следующей функции
void f(int &a, int &b)
{
a = 0, b = 0;
}
компилятор может свести к той же последовательности вычислений, что и
void f(int &a, int &b)
{
b = 0;
a = 0;
}
Компилятор может и вообще выбросить эти присваивания, если увидит, что они не влияют на видимый результат:
// VC++ 10.0 /O2 /Ob2#include <stdio.h>
void f(int &a, int &b)
{
a = 0, b = 0;
}
int main()
{
//00401000 push esi int A = 1, B = 2;
printf("A = %d, B = %d\n", A, B);
//00401001 mov esi,dword ptr [__imp__printf (4020A0h)]
//00401007 push 2
//00401009 push 1
//0040100B push offset string "A = %d, B = %d\n" (4020F4h)
//00401010 call esi
f(A, B);
printf("exit\n");
//00401012 push offset string "exit\n" (4020ECh)
//00401017 call esi
//00401019 add esp,10h
}
//0040101C xor eax,eax
//0040101E pop esi
//0040101F ret
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>все таки стандарт C намного проще там четко сказано любые побочные эффекты J>(про операторы было из С) а в плюсах какие то страсти мордасти создается J>ощущение что собрались извращенцы и пишут стандарт C++ для таких же извращенцев J>как они сами
Читаю С++ код в разделе и жалею С++ программистов. Надеюсь мне никогда не придётся перейти с Си на С++.
Для нас [Thompson, Rob Pike, Robert Griesemer] это было просто исследование. Мы собрались вместе и решили, что ненавидим C++ [смех].
Здравствуйте, jyuyjiyuijyu, Вы писали:
V>>7. Accessing an object designated by a volatile lvalue (3.10), modifying an object, calling a library I/O V>>function, or calling a function that does any of those operations are all side effects, which are changes in the V>>state of the execution environment. V>>[/q] V>>В примере было чтение не volatile переменной и что теперь? Как себя компилятор должен повести? J>тоесть отличаются побочные эффекты для J>&& || и для , ?: которые вляют на порядок вычисления ?
А ещё они чем отличаются тоже будешь выискивать? А не проще ли обойти болото, а не лезть в него?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]