Переменная __macro<char>::_ принимает значение, но ее значение используется между точками следования. UB.
(Побочные def(x) эффекты могут наступить после того как будут вычислены acc(x).)
C>Переменная __macro<char>::_ принимает значение, но ее значение используется между точками следования. UB.
ээ она принимает тип в sizeof внутри typeof а оно не вычислимое ниразу где тут уб ? C>(Побочные def(x) эффекты могут наступить после того как будут вычислены acc(x).)
это вообще интересно а как же запятая ? она одна из немногих порядок гарантирует
C>Переменная __macro<char>::_ принимает значение, но ее значение используется между точками следования. UB. C>(Побочные def(x) эффекты могут наступить после того как будут вычислены acc(x).)
C>Дважды модифицирована переменная (hj++) между точками следования. UB.
#define is_digit(x) (def(x),(acc(x) >= '0' && acc(x) <= '9') ? true : false)
как я это вижу первое это код после раскрытия def
#define def(c) (__macro<typeof(c)>::_ = c)
одно вычисление аргумента макроса потому что выражение внутри typeof
не вычисляется дальше код после раскрытия #define acc(c) (__macro<typeof(c)>::_)
тут тоже аргумент нигде не вычисляется вроде все нормально ?
или нет ?
Здравствуйте, jyuyjiyuijyu, Вы писали:
C>>(Побочные def(x) эффекты могут наступить после того как будут вычислены acc(x).) J>это вообще интересно а как же запятая ? она одна из немногих порядок гарантирует
Это другая запятая.
int i = 20, j = i + 10
f(i++, i++)
это две разных запятых. В первом случае нет ub.
Здравствуйте, Valen, Вы писали:
V>Здравствуйте, jyuyjiyuijyu, Вы писали:
C>>>(Побочные def(x) эффекты могут наступить после того как будут вычислены acc(x).) J>>это вообще интересно а как же запятая ? она одна из немногих порядок гарантирует V>Это другая запятая. V>int i = 20, j = i + 10 V>f(i++, i++) V>это две разных запятых. В первом случае нет ub.
с этим согласен но там запятая как раз имеет свое первоочередное значение
или оъясните подробнее почему там запятая не сработает
Здравствуйте, jyuyjiyuijyu, Вы писали:
C>>>>(Побочные def(x) эффекты могут наступить после того как будут вычислены acc(x).) J>>>это вообще интересно а как же запятая ? она одна из немногих порядок гарантирует V>>Это другая запятая. V>>int i = 20, j = i + 10 V>>f(i++, i++) V>>это две разных запятых. В первом случае нет ub. J>с этим согласен но там запятая как раз имеет свое первоочередное значение J>или оъясните подробнее почему там запятая не сработает
Потому что нет присваивания.
В стандарте есть другой пример: f(a, (t = 3, t + 2), b), ниже примера сказано что второй аргумент будет равен 5, а не ub.
Здравствуйте, Valen, Вы писали:
V>Здравствуйте, jyuyjiyuijyu, Вы писали:
C>>>>>(Побочные def(x) эффекты могут наступить после того как будут вычислены acc(x).) J>>>>это вообще интересно а как же запятая ? она одна из немногих порядок гарантирует V>>>Это другая запятая. V>>>int i = 20, j = i + 10 V>>>f(i++, i++) V>>>это две разных запятых. В первом случае нет ub. J>>с этим согласен но там запятая как раз имеет свое первоочередное значение J>>или оъясните подробнее почему там запятая не сработает V>Потому что нет присваивания. V>В стандарте есть другой пример: f(a, (t = 3, t + 2), b), ниже примера сказано что второй аргумент будет равен 5, а не ub.
я вас непонимаю
1) #define is_digit(x) (def(x),(acc(x) >= '0' && acc(x) <= '9') ? true : false)
#define def(c) (__macro<typeof(c)>::_ = c)
это присваивание потом заапятая потом только чтение
#define acc(c) (__macro<typeof(c)>::_)
где тут уб никак непойму
Здравствуйте, Valen, Вы писали:
V>Здравствуйте, jyuyjiyuijyu, Вы писали:
C>>>>>(Побочные def(x) эффекты могут наступить после того как будут вычислены acc(x).) J>>>>это вообще интересно а как же запятая ? она одна из немногих порядок гарантирует V>>>Это другая запятая. V>>>int i = 20, j = i + 10 V>>>f(i++, i++) V>>>это две разных запятых. В первом случае нет ub. J>>с этим согласен но там запятая как раз имеет свое первоочередное значение J>>или оъясните подробнее почему там запятая не сработает V>Потому что нет присваивания. V>В стандарте есть другой пример: f(a, (t = 3, t + 2), b), ниже примера сказано что второй аргумент будет равен 5, а не ub.
приваиваем
(__macro<typeof(c)>::_ = c)
запятая ,
читаем
(__macro<typeof(c)>::_)
до запятой все побочные эффекты пройдут даже если приваиваемое такой например
(__macro<typeof(c)>::_ = c++)
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>приваиваем J>(__macro<typeof(c)>::_ = c) J>запятая , J>читаем J>(__macro<typeof(c)>::_) J>до запятой все побочные эффекты пройдут даже если приваиваемое такой например J>(__macro<typeof(c)>::_ = c++)
Ну так порядок вычисления не определён. Чтение может наступить раньше записи.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, Vain, Вы писали:
V>Здравствуйте, jyuyjiyuijyu, Вы писали:
J>>приваиваем J>>(__macro<typeof(c)>::_ = c) J>>запятая , J>>читаем J>>(__macro<typeof(c)>::_) J>>до запятой все побочные эффекты пройдут даже если приваиваемое такой например J>>(__macro<typeof(c)>::_ = c++) V>Ну так порядок вычисления не определён. Чтение может наступить раньше записи.
чтение не может быть раньше записи порядок жестко определен для 4 операторов
&& || , ?: чтение никак не может быть раньше записи у всех этих операторов
первым вычисляется выражение слева со всеми побочными эффектами не может сначала
произойти чтение а потом запись
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>>>приваиваем J>>>(__macro<typeof(c)>::_ = c) J>>>запятая , J>>>читаем J>>>(__macro<typeof(c)>::_) J>>>до запятой все побочные эффекты пройдут даже если приваиваемое такой например J>>>(__macro<typeof(c)>::_ = c++) V>>Ну так порядок вычисления не определён. Чтение может наступить раньше записи. J>чтение не может быть раньше записи порядок жестко определен для 4 операторов J>&& || , ?: чтение никак не может быть раньше записи у всех этих операторов
Будет проще понять, если представить всё выражение в виде дерева выражений:
Порядок определён между нодами с общим родителем, не глубже. Другими словами порядок вычисления листьев может быть таким: 3->1->4->2. Поэтому при вычислении подвыражений результат вычисления самих выражений может измениться из-за порядка между подвыражениями. А сами операторы определяют (если определяют, к примеру, к запятой это не относится) порядок только между своими операндами, но не глубже.
J>первым вычисляется выражение слева со всеми побочными эффектами не может сначала J>произойти чтение а потом запись
В случае с запятой — это не так
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, Vain, Вы писали:
V>Здравствуйте, jyuyjiyuijyu, Вы писали:
J>>>>приваиваем J>>>>(__macro<typeof(c)>::_ = c) J>>>>запятая , J>>>>читаем J>>>>(__macro<typeof(c)>::_) J>>>>до запятой все побочные эффекты пройдут даже если приваиваемое такой например J>>>>(__macro<typeof(c)>::_ = c++) V>>>Ну так порядок вычисления не определён. Чтение может наступить раньше записи. J>>чтение не может быть раньше записи порядок жестко определен для 4 операторов J>>&& || , ?: чтение никак не может быть раньше записи у всех этих операторов V>Будет проще понять, если представить всё выражение в виде дерева выражений: V>
V>Порядок определён между нодами с общим родителем, не глубже. Другими словами порядок вычисления листьев может быть таким: 3->1->4->2. Поэтому при вычислении подвыражений результат вычисления самих выражений может измениться из-за порядка между подвыражениями. А сами операторы определяют (если определяют, к примеру, к запятой это не относится) порядок только между своими операндами, но не глубже.
J>>первым вычисляется выражение слева со всеми побочными эффектами не может сначала J>>произойти чтение а потом запись V>В случае с запятой — это не так
не может вычислятся часть правого подвыражения пока не вычислено все левое выражение
со всеми побочными эффектами и к запятой это тоже относится
иначе весь код который сейчас работает просто бы рухнул
язык гарантирует вычисление всего левого выражения перед вычислением правого
иначе например вы хотите сказать что этот код тоже не верный
n++ != first_magic++ && first_magic != read_second_magic(n) ???
если рассуждать как вы то тут вообще все плохо
или вот
int k = 1, u = 1, n = 1;
k = n++ + u++, n = k++ + u++, u = n++ + k++;
printf("%d %d %d\n", k, u, n);
output: 4 7 5
это вообще смертельно было бы однако работает как и ожидается
или покажите где не так ?
согласен баг есть тут
void call(int,int,int);
int v = 1, a, b, c;
call((v++,a=v),(v++,b=v),(v++,c=v));
тут да он делает инкремент всем левым выражениям сразу а потом присваивает всем одно число
но тут три группы операторов задающих порядок вычисления и в каком порядке считать между ними
ему решать лиш бы порядок в каждой отдельной группе сохранился он сохраняется но
из за того что мы разделили v между ними имеем баг остальные случаи я считаю сказки
покажите неправильно работающий код когда он вычисляет только часть выражения
в операторах && || ?: , и недовычисляя переходит к правому и из за этого все ломается
думается мне что не приведете
или вот тут есть баг согласен
int k = 1, u = 1, n = 1;
(k = n++ + u++, n = k++ + u++, u = n++ + k++)
+ (k = n++ + u++, n = k++ + u++, u = n++ + k++)
+ (k = n++ + u++, n = k++ + u++, u = n++ + k++);
printf("%d %d %d\n", k, u, n);
в том смысле что он может вычислить подвыражение k = n++ + u++ в первом выражении (k = n++ + u++, n = k++ + u++, u = n++ + k++)
и перейти считать это же подвыражение во втором выжении (k = n++ + u++, n = k++ + u++, u = n++ + k++) и потом вообще начинать считать второе подвыражение n = k++ + u++ с предвычисленными k n u со всех трех подвыражений
но в отдельно взятом (k = n++ + u++, n = k++ + u++, u = n++ + k++)
он не может ничего вычислять справа от запятой пока не вчыислит все от предыдущего выражения слева со всеми побочными эффектами
Здравствуйте, jyuyjiyuijyu, Вы писали:
J> не может вычислятся часть правого подвыражения пока не вычислено все левое выражение J>со всеми побочными эффектами и к запятой это тоже относится J>иначе весь код который сейчас работает просто бы рухнул
На другом компиляторе он и рухнет если так и дальше будете писать.
J>язык гарантирует вычисление всего левого выражения перед вычислением правого J>иначе например вы хотите сказать что этот код тоже не верный J>n++ != first_magic++ && first_magic != read_second_magic(n) ???
В данном случае неперегруженный оператор "&&" требует чтобы к моменту его вычисления левый операнд уже был вычислен, т.к. этот оператор вычисляет операнды в предопределённом порядке (в отличии, к примеру, от бинарного оператора "&"). А дальнейшее поведение думаю будет зависить от "аггрессивности" оптимизатора.
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>это вообще смертельно было бы однако работает как и ожидается
Не вижу противоречия.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]