И снова ++x + ++x !!!

Тема в разделе "LANGS.C", создана пользователем _DEN_, 11 май 2007.

  1. RedLord

    RedLord Member

    Публикаций:
    0
    Регистрация:
    23 июн 2005
    Сообщения:
    183
    Адрес:
    Ukraine
    VC6.0
    в Debug: результат 3
    в Release с оптимизацией (Max. Speed) - 4;
    в Release с отключенной оптимизацией - 3;

    Intel 9.0

    в Debug: результат 3
    в Release с оптимизацией (Max. Speed) - 3;
     
  2. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    RedLord
    Я не раз замечал, что, если дело не касается FPU, MMX/SSE, то VC8 оптимизирует существенно лучше, чем Intel 9.
     
  3. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    _DEN_
    Видимо, Nouzui прав - так сделано для упрощения самого Стандарта. Т.е. здесь UB - следствие общего положения об неопределённости порядка вычисления аргументов/операндов, без учёта специфики оператора присваивания:
    i = ++i + 1 можно представить как
    Assign(i, ++i + 1)
    :derisive:
     
  4. RedLord

    RedLord Member

    Публикаций:
    0
    Регистрация:
    23 июн 2005
    Сообщения:
    183
    Адрес:
    Ukraine
    green
    ха. на Intel и Comeau при объявлении

    int plus(const int& a, const int& b) - имеем 4
    int plus(int& a, int& b) - тоже 4

    int plus(int a, int b) - 3

    оптимизация выполняется по разному у VC и этих компилеров.
     
  5. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    RedLord
    VC8 даёт 4 в обеих вариантах.
     
  6. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    там 3 варианта ;)
     
  7. maxdiver

    maxdiver Max

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    308
    Адрес:
    Саратов
    __DEN__
    :)
    Я не пойму, ты выборочно что ли посты читаешь? :) Ответы на все твои вопросы были уже даны.

    Посты 29 и 36:
    Короче, попробуй опиши все случаи: когда результат определён, а когда нет. Да и зачем? Это только усложнит компиляторам оптимизацию.

    (ответ был уже дан в посте 36)
    Честно говоря, у подумал, что это была неудачная шутка :) Оператор return - это оператор return, а не часть какого-либо выражения. Он имеет вид: return <выражение>; Поэтому (return 1), 2; - это, извините, бред. И это тоже:
     
  8. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    maxdiver

    И чем return хуже остальных операторов? С точки зрения логики языка это точно такой же оператор. Просто видимо с наименьшим приоритетом.


    ARMAGEDDONT

    Превед, кросавчег.
     
  9. maxdiver

    maxdiver Max

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    308
    Адрес:
    Саратов
    __DEN__
    Он "хуже" тем, что это другой оператор :)
    Он обладает другими свойствами, и применять его в других выражениях - то же самое, что применять, скажем, break:
    Код (Text):
    1. x = 5 + return 1; // ))))))
    2. x = break, 1; // )))))))
    Или ты считаешь такие выражения нормальными? ;)
     
  10. maxdiver

    maxdiver Max

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    308
    Адрес:
    Саратов
    __DEN__
    Ты, по-видимому, недопонимаешь разницу между разными операторами. Возможно, это происходит вследствие путаницы в русских названиях: в английском языке return, break и т.д. именуются "statements", а +, * - "operators", но на русский и то, и другое переводится как "операторы".
    Например, statements - это goto, if, switch, return, case, break, выражение (expression). Очевидно, что выражение не может включать в себя statements (естественно, кроме других выражений). Выражение может включать в себя операторы (operators).

    Таким образом, выражение не может включать в себя return. Оператор return - это отдельная конструкция, равноправная с выражением. Поэтому, как ты выразился, "с точки зрения логики языка он хуже других операторов" :) Теперь, надеюсь, ясно, что никакого приоритета он не имеет и иметь не может.
     
  11. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    maxdiver
    Насчёт приоритета return - это я фигурально. :derisive:

    Кстати, мне идея языка Mathematica жутко понравилась: "Everything is expression". :)
     
  12. RedLord

    RedLord Member

    Публикаций:
    0
    Регистрация:
    23 июн 2005
    Сообщения:
    183
    Адрес:
    Ukraine
    вернусь к ++i
    при передаче по ссылке - все понятно. действительно 4.
    а вот если передавать по значению имеем варианты (последовательность вычисления аргументов примем слева-на-право)
    (Nouzui выше описывал, только опустил момент, что мы передаем по значению, и создается временная переменная)
    то есть вызов func(++i, ++i) фактически можно рассматривать так:
    вариант 1
    ++i;
    ++i;
    tmp1(i)
    tmp2(i)
    func(tmp1, tmp2);

    вариант2
    ++i;
    tmp1(i)
    ++i
    tmp2(i)
    func(tmp1, tmp2);
    в первом случаем результат 4, а во втором - 3.

    вопрос в том, имеет ли право оптимизация как в варианте 1 ?
     
  13. maxdiver

    maxdiver Max

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    308
    Адрес:
    Саратов
    RedLord
    Конечно, имеет право. Это уже неоднократно обсуждалось в предыдущих постах.
     
  14. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    RedLord

    ВСПООООООООООООМНИЛ! Профессор, я вспомнил :)

    У Саттера было сказано что мол вот такое выражение не безопасно с точки зрения исключений:

    Код (Text):
    1. typedef boost::shared_ptr<SomeClass> SomeClassPtr;
    2.  
    3. void foo(SomeClassPtr a, SomeClassPtr b);
    4.  
    5. //..............
    6.  
    7. foo(SomeClassPtr(new SomeClass), SomeClassPtr(new SomeClass));
    Каменты были такие: мол вычисление параметров не обязано выполняться последовательно - компилер имеет право сначала создать оба экземпляра объектов, а потом уже только сконструировать смартпоинтеры. Ну и дальше ясно что если в таком случае второй конструктор сгенерить исключение, то произойдет утечка, т.к. первый дамбпоинтер еще не захендлен.
    Отсюда можно сделать вывод о том, что вычисления не обязаны быть атомарными, и plus(++i, ++i) это действительно UB.
     
  15. maxdiver

    maxdiver Max

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    308
    Адрес:
    Саратов
    __DEN__
    Мда.
    Уже тысячу раз был приведён и текст Стандарта, и пояснения к нему разные люди тут писали. Но тем мне менее:
    ?
     
  16. maxdiver

    maxdiver Max

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    308
    Адрес:
    Саратов
    __DEN__
    А про "безопасность с точки зрения исключений" следует думать только тогда, когда хотя бы изучен синтаксис языка.
     
  17. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    maxdiver

    > А про "безопасность с точки зрения исключений" следует думать только тогда, когда хотя бы изучен синтаксис языка.

    Не понял? Это что за намеки?
     
  18. RedLord

    RedLord Member

    Публикаций:
    0
    Регистрация:
    23 июн 2005
    Сообщения:
    183
    Адрес:
    Ukraine
    maxdiver

    в результате этого права имеем утечку памяти в примере приведенном _DEN_
     
  19. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    да, C вещь жуткая, кто же спорит? но именно поэтому он и C
     
  20. maxdiver

    maxdiver Max

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    308
    Адрес:
    Саратов
    _DEN_
    А какая может быть "безопасность с точки зрения исключений", если имеется незнание основ языка, например, действия операторов или порядка вычислений аргументов функций?

    RedLord
    Поэтому надо создавать локальные переменные, а иначе - получаем небезопасный код.