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.]
[Даю очевидные ответы на риторические вопросы]
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.