wtf?
От: e113c08d6cf14afb  
Дата: 07.05.11 00:16
Оценка:
#include <stdio.h>
#include <boost/typeof/typeof.hpp>

template<class T>
struct __macro
{
    __declspec(thread) static T _;
};

template<class T>
T __macro<T>::_;

#define def(c) (__macro<typeof(c)>::_ = c)
#define acc(c) (__macro<typeof(c)>::_)

#define is_digit(x) (def(x),(acc(x) >= '0' && acc(x) <= '9') ? true : false)
#define is_bugit(x) ((x >= '0' && x <= '9') ? true : false)

int main()
{
    char hj;
    
    hj = '9';
    printf("test->") && is_bugit(hj++) && printf("ok\n") || puts("no");

    hj = '9';
    printf("test->") && is_digit(hj++) && printf("ok\n") || puts("no");
}
Re: wtf?
От: Ytz https://github.com/mtrempoltsev
Дата: 07.05.11 05:42
Оценка:
Действительно wtf? Что сказать хотел?
Re: wtf?
От: jazzer Россия Skype: enerjazzer
Дата: 07.05.11 07:23
Оценка:
Здравствуйте, e113c08d6cf14afb, Вы писали:

E>
E>#define is_digit(x) (def(x),(acc(x) >= '0' && acc(x) <= '9') ? true : false)
E>#define is_bugit(x) ((x >= '0' && x <= '9') ? true : false)
E>


И в чем вопрос? В каком из макросов больше багов?
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: wtf?
От: Chorkov Россия  
Дата: 07.05.11 07:52
Оценка: +1
Здравствуйте, e113c08d6cf14afb, Вы писали:

#define is_digit(x) (def(x),(acc(x) >= '0' && acc(x) <= '9') ? true : false)

Переменная __macro<char>::_ принимает значение, но ее значение используется между точками следования. UB.
(Побочные def(x) эффекты могут наступить после того как будут вычислены acc(x).)


#define is_bugit(x) ((x >= '0' && x <= '9') ? true : false)

Дважды модифицирована переменная (hj++) между точками следования. UB.
Re[2]: wtf?
От: jyuyjiyuijyu  
Дата: 07.05.11 08:31
Оценка:
Здравствуйте, Chorkov, Вы писали:

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


C>
C>#define is_digit(x) (def(x),(acc(x) >= '0' && acc(x) <= '9') ? true : false)
C>

C>Переменная __macro<char>::_ принимает значение, но ее значение используется между точками следования. UB.
ээ она принимает тип в sizeof внутри typeof а оно не вычислимое ниразу где тут уб ?
C>(Побочные def(x) эффекты могут наступить после того как будут вычислены acc(x).)
это вообще интересно а как же запятая ? она одна из немногих порядок гарантирует


C>
C>#define is_bugit(x) ((x >= '0' && x <= '9') ? true : false)
C>

C>Дважды модифицирована переменная (hj++) между точками следования. UB.
Re[2]: wtf?
От: jyuyjiyuijyu  
Дата: 07.05.11 08:46
Оценка:
Здравствуйте, jazzer, Вы писали:

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


E>>
E>>#define is_digit(x) (def(x),(acc(x) >= '0' && acc(x) <= '9') ? true : false)
E>>#define is_bugit(x) ((x >= '0' && x <= '9') ? true : false)
E>>


J>И в чем вопрос? В каком из макросов больше багов?

да перечислите все баги, интересно
Re[2]: wtf?
От: jyuyjiyuijyu  
Дата: 07.05.11 09:15
Оценка:
Здравствуйте, Chorkov, Вы писали:

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


C>
C>#define is_digit(x) (def(x),(acc(x) >= '0' && acc(x) <= '9') ? true : false)
C>

C>Переменная __macro<char>::_ принимает значение, но ее значение используется между точками следования. UB.
C>(Побочные def(x) эффекты могут наступить после того как будут вычислены acc(x).)


C>
C>#define is_bugit(x) ((x >= '0' && x <= '9') ? true : false)
C>

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)>::_)
тут тоже аргумент нигде не вычисляется вроде все нормально ?
или нет ?
Re: wtf?
От: Vain Россия google.ru
Дата: 07.05.11 13:22
Оценка:
Здравствуйте, e113c08d6cf14afb, Вы писали:

Здесь
Автор: topkay
Дата: 07.08.05
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[3]: wtf?
От: Valen  
Дата: 07.05.11 13:39
Оценка: 1 (1)
Здравствуйте, jyuyjiyuijyu, Вы писали:

C>>(Побочные def(x) эффекты могут наступить после того как будут вычислены acc(x).)

J>это вообще интересно а как же запятая ? она одна из немногих порядок гарантирует
Это другая запятая.
int i = 20, j = i + 10
f(i++, i++)
это две разных запятых. В первом случае нет ub.
Re[2]: wtf?
От: Valen  
Дата: 07.05.11 13:43
Оценка:
Здравствуйте, Chorkov, Вы писали:

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


C>
C>#define is_bugit(x) ((x >= '0' && x <= '9') ? true : false)
C>

C>Дважды модифицирована переменная (hj++) между точками следования. UB.

Если я правильно понимаю, то этот код выродится в
((hj++ >= '0' && hj++ <= '9') ? true : false)

Но стандарт говорит, что не перегруженный оператор "&&" есть sequence point, потому здесь нет ub.
Re[4]: wtf?
От: jyuyjiyuijyu  
Дата: 07.05.11 16:43
Оценка:
Здравствуйте, Valen, Вы писали:

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


C>>>(Побочные def(x) эффекты могут наступить после того как будут вычислены acc(x).)

J>>это вообще интересно а как же запятая ? она одна из немногих порядок гарантирует
V>Это другая запятая.
V>int i = 20, j = i + 10
V>f(i++, i++)
V>это две разных запятых. В первом случае нет ub.
с этим согласен но там запятая как раз имеет свое первоочередное значение
или оъясните подробнее почему там запятая не сработает
Re[5]: wtf?
От: Valen  
Дата: 07.05.11 16:57
Оценка:
Здравствуйте, 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.
Re[6]: wtf?
От: jyuyjiyuijyu  
Дата: 07.05.11 17:03
Оценка:
Здравствуйте, 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)>::_)
где тут уб никак непойму
Re[6]: wtf?
От: jyuyjiyuijyu  
Дата: 07.05.11 17:08
Оценка:
Здравствуйте, 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++)
Re[7]: wtf?
От: Vain Россия google.ru
Дата: 07.05.11 19:53
Оценка:
Здравствуйте, 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.]
[Даю очевидные ответы на риторические вопросы]
Re[8]: wtf?
От: jyuyjiyuijyu  
Дата: 07.05.11 19:56
Оценка:
Здравствуйте, Vain, Вы писали:

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


J>>приваиваем

J>>(__macro<typeof(c)>::_ = c)
J>>запятая ,
J>>читаем
J>>(__macro<typeof(c)>::_)
J>>до запятой все побочные эффекты пройдут даже если приваиваемое такой например
J>>(__macro<typeof(c)>::_ = c++)
V>Ну так порядок вычисления не определён. Чтение может наступить раньше записи.
чтение не может быть раньше записи порядок жестко определен для 4 операторов
&& || , ?: чтение никак не может быть раньше записи у всех этих операторов
первым вычисляется выражение слева со всеми побочными эффектами не может сначала
произойти чтение а потом запись
Re[9]: wtf?
От: Vain Россия google.ru
Дата: 07.05.11 22:30
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>>>приваиваем

J>>>(__macro<typeof(c)>::_ = c)
J>>>запятая ,
J>>>читаем
J>>>(__macro<typeof(c)>::_)
J>>>до запятой все побочные эффекты пройдут даже если приваиваемое такой например
J>>>(__macro<typeof(c)>::_ = c++)
V>>Ну так порядок вычисления не определён. Чтение может наступить раньше записи.
J>чтение не может быть раньше записи порядок жестко определен для 4 операторов
J>&& || , ?: чтение никак не может быть раньше записи у всех этих операторов
Будет проще понять, если представить всё выражение в виде дерева выражений:
[hj++ >= '0' && hj++ <= '9']
        /          \
[hj++ >= '0']  [hj++ <= '9']
   /     \        /     \
[hj++]  ['0']  [hj++]  ['9']
  1       2      3       4

Порядок определён между нодами с общим родителем, не глубже. Другими словами порядок вычисления листьев может быть таким: 3->1->4->2. Поэтому при вычислении подвыражений результат вычисления самих выражений может измениться из-за порядка между подвыражениями. А сами операторы определяют (если определяют, к примеру, к запятой это не относится) порядок только между своими операндами, но не глубже.

J>первым вычисляется выражение слева со всеми побочными эффектами не может сначала

J>произойти чтение а потом запись
В случае с запятой — это не так
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[10]: wtf?
От: jyuyjiyuijyu  
Дата: 07.05.11 23:53
Оценка:
Здравствуйте, 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>[hj++ >= '0' && hj++ <= '9']
V>        /          \
V>[hj++ >= '0']  [hj++ <= '9']
V>   /     \        /     \
V>[hj++]  ['0']  [hj++]  ['9']
V>  1       2      3       4
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 между ними имеем баг остальные случаи я считаю сказки
покажите неправильно работающий код когда он вычисляет только часть выражения
в операторах && || ?: , и недовычисляя переходит к правому и из за этого все ломается
думается мне что не приведете
Re[10]: wtf?
От: jyuyjiyuijyu  
Дата: 08.05.11 00:07
Оценка:
Здравствуйте, Vain, Вы писали:

или вот тут есть баг согласен
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++)
он не может ничего вычислять справа от запятой пока не вчыислит все от предыдущего выражения слева со всеми побочными эффектами
Re[11]: wtf?
От: Vain Россия google.ru
Дата: 08.05.11 01:01
Оценка:
Здравствуйте, 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.]
[Даю очевидные ответы на риторические вопросы]
Re[12]: wtf?
От: jyuyjiyuijyu  
Дата: 08.05.11 01:38
Оценка:
Здравствуйте, 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) он этот
код интерпретировать не сможет
Re[12]: wtf?
От: jyuyjiyuijyu  
Дата: 08.05.11 01:45
Оценка:
Здравствуйте, Vain, Вы писали:

просто покажите реальный код неправильно работающий все и ненадо будет спорить
или покажите где этот код не как ожидается будет работать
#define is_digit(x) (def(x),(acc(x) >= '0' && acc(x) <= '9') ? true : false)
Re[12]: wtf?
От: jyuyjiyuijyu  
Дата: 08.05.11 01:49
Оценка:
Здравствуйте, Vain, Вы писали:

давайте перейдем к фактам покажите неправильно работающий код
Re[12]: wtf?
От: jyuyjiyuijyu  
Дата: 08.05.11 01:54
Оценка:
Здравствуйте, Vain, Вы писали:

тоесть вы сами с этим не сталкивались ? если сталкивались то
покажите неправильно работающий код
Re[13]: wtf?
От: Vain Россия google.ru
Дата: 08.05.11 02:24
Оценка:
Здравствуйте, 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.]
[Даю очевидные ответы на риторические вопросы]
Re[14]: wtf?
От: jyuyjiyuijyu  
Дата: 08.05.11 03:03
Оценка:
Здравствуйте, 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), который сам является частью другого подвыражения.

ладно останемся каждый при своем мнении в любом случае спасибо за беседу
приятно было пообщаться
Re[10]: wtf?
От: Valen  
Дата: 08.05.11 05:06
Оценка:
Здравствуйте, Vain, Вы писали:

V>Будет проще понять, если представить всё выражение в виде дерева выражений:

V>
V>[hj++ >= '0' && hj++ <= '9']
V>        /          \
V>[hj++ >= '0']  [hj++ <= '9']
V>   /     \        /     \
V>[hj++]  ['0']  [hj++]  ['9']
V>  1       2      3       4
V>

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 ?
Re[3]: wtf?
От: rg45 СССР  
Дата: 08.05.11 09:35
Оценка: :))
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>да перечислите все баги, интересно


Глазам не верю! Ты использовал знак препинания!
--
Справедливость выше закона. А человечность выше справедливости.
Re[11]: wtf?
От: Vain Россия google.ru
Дата: 08.05.11 11:23
Оценка:
Здравствуйте, 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.]
[Даю очевидные ответы на риторические вопросы]
Re[12]: wtf?
От: jyuyjiyuijyu  
Дата: 09.05.11 20:27
Оценка:
Здравствуйте, 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>Ну с операторами && и || всё строго должно быть, иначе бы были интересные побочные эффекты.
теперь вам осталось оюяснить чем && || отличаются от , ?: в плане
порядка вычисления выражений я понял так что для вас в && || ничего не может
считатся справа пока не вычислено все выражение слева но почему то для
оператора , (запятая) у вас такой гарантии нет это лично для меня удивительно
Re[13]: wtf?
От: Vain Россия google.ru
Дата: 09.05.11 22:00
Оценка:
Здравствуйте, 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.]
[Даю очевидные ответы на риторические вопросы]
Re[14]: wtf?
От: jyuyjiyuijyu  
Дата: 09.05.11 22:30
Оценка:
Здравствуйте, 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.

разве это не гарантирует порядок вычисления ? вроде тут ясно сказано что ничего справа не будет вычиислятся пока все выражение слева со всеми побочными эффекитами не вычислится
Re[14]: wtf?
От: jyuyjiyuijyu  
Дата: 09.05.11 22:36
Оценка:
Здравствуйте, 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.

помоему одно и тоже говорится про порядок вычисления между && и ,
Re[15]: wtf?
От: Vain Россия google.ru
Дата: 10.05.11 09:14
Оценка:
Здравствуйте, 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.]
[Даю очевидные ответы на риторические вопросы]
Re[16]: wtf?
От: jyuyjiyuijyu  
Дата: 10.05.11 10:20
Оценка:
Здравствуйте, 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 переменной для опретора , (запятая) а для
&& (логическое и) гарантировать изменение любой переменной это же
чистой воды бред сумашедшего
Re[17]: wtf?
От: jyuyjiyuijyu  
Дата: 10.05.11 10:32
Оценка:
а вот интересно как в жизни например MSVC/C++ всегда выполняет все
побочные эффекты в операторе , (запятая) перед тем как вычислять
выражение справа а GCC интересно выполняет ? кто нибудь может проверить
на всех уровнях оптимизации ?
Re[18]: wtf?
От: jyuyjiyuijyu  
Дата: 10.05.11 10:43
Оценка:
все таки стандарт C намного проще там четко сказано любые побочные эффекты
(про операторы было из С) а в плюсах какие то страсти мордасти создается
ощущение что собрались извращенцы и пишут стандарт C++ для таких же извращенцев
как они сами
Re[18]: wtf?
От: Masterkent  
Дата: 10.05.11 15:35
Оценка:
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
Re[19]: wtf?
От: Sorc17 Россия  
Дата: 10.05.11 17:40
Оценка: -1
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>все таки стандарт C намного проще там четко сказано любые побочные эффекты

J>(про операторы было из С) а в плюсах какие то страсти мордасти создается
J>ощущение что собрались извращенцы и пишут стандарт C++ для таких же извращенцев
J>как они сами

Читаю С++ код в разделе и жалею С++ программистов. Надеюсь мне никогда не придётся перейти с Си на С++.
Для нас [Thompson, Rob Pike, Robert Griesemer] это было просто исследование. Мы собрались вместе и решили, что ненавидим C++ [смех].
Re[17]: wtf?
От: Vain Россия google.ru
Дата: 10.05.11 19:30
Оценка:
Здравствуйте, 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.]
[Даю очевидные ответы на риторические вопросы]
Re[18]: wtf?
От: jyuyjiyuijyu  
Дата: 10.05.11 20:53
Оценка:
Здравствуйте, Vain, Вы писали:

V>Здравствуйте, 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>>&& || и для , ?: которые вляют на порядок вычисления ?
V>А ещё они чем отличаются тоже будешь выискивать? А не проще ли обойти болото, а не лезть в него?
ну а как вам такой код из стандарта
f(a, (t=3, t+2), c) : t == 5
здесь точно такой же случай присваивание а следом чтение
значит все таки есть гарантия ?
отличаются они только тем что тут чтение и изменение
а там просто чтение
Re[19]: wtf?
От: jyuyjiyuijyu  
Дата: 10.05.11 21:00
Оценка:
не мне бы конечно было пофиг но я часто использую этот оператор , (запятая)
поэтому и столько вопросов получается если раньше я его без зазрения совести
использовал то теперь вская муть будет мнится ? поэтому и хотелось бы разобратся
Re[19]: wtf?
От: Masterkent  
Дата: 11.05.11 05:51
Оценка:
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>>>&& || и для , ?: которые вляют на порядок вычисления ?
V>>А ещё они чем отличаются тоже будешь выискивать? А не проще ли обойти болото, а не лезть в него?
J>ну а как вам такой код из стандарта
J>f(a, (t=3, t+2), c) : t == 5
J>здесь точно такой же случай присваивание а следом чтение
J>значит все таки есть гарантия ?

Для абстрактной машины есть: если t имеет целочисленный тип, то изменение объекта t в t=3 должно быть завершено до чтения t в t+2. Компилятор должен обеспечить такой же видимый результат работы программы, как если бы она выполнялась на абстрактной машине. Бóльших гарантий и не нужно.
Re[20]: wtf?
От: jyuyjiyuijyu  
Дата: 11.05.11 07:04
Оценка:
Здравствуйте, Masterkent, Вы писали:

M>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>>>>&& || и для , ?: которые вляют на порядок вычисления ?
V>>>А ещё они чем отличаются тоже будешь выискивать? А не проще ли обойти болото, а не лезть в него?
J>>ну а как вам такой код из стандарта
J>>f(a, (t=3, t+2), c) : t == 5
J>>здесь точно такой же случай присваивание а следом чтение
J>>значит все таки есть гарантия ?

M>Для абстрактной машины есть: если t имеет целочисленный тип, то изменение объекта t в t=3 должно быть завершено до чтения t в t+2. Компилятор должен обеспечить такой же видимый результат работы программы, как если бы она выполнялась на абстрактной машине. Бóльших гарантий и не нужно.

ну значит и этот код для абстрактной машины значит тоже что и я думаю
а как она это обеспечит неважно пусть хоть на луну слетает между делом
#define def(c) (__macro<typeof(c)>::_ = c)
#define acc(c) (__macro<typeof(c)>::_)

#define is_digit(x) (def(x),(acc(x) >= '0' && acc(x) <= '9') ? true : false)

по сути это же
((__macro<typeof(c)>::_ = c), (__macro<typeof(c)>::_ <> '$') ? true : false)
ни о каком чтении раньше присваивания и речи быть не можеть же ?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.