LINUX.ORG.RU
ФорумTalks

i += i++ + ++i


0

1

Привет.

Я тут случайно узнал что следующий код дает разный результат для разных языков. Всю жизнь был уверен что оно работает одинаково кругом, и возвращает 4.

// i -- целочисленная переменная
i = 0;
i += i++ + ++i;
// чему равно i?

Так в C, Perl, PHP оно выводит 4, в Java, Javascript же 2. Причину я понял (момент вычисления i++), но зачем они такое сделали??? И еще вопрос. Есть ли гарантия что все реализации Java (JVM и компилятора) дадут 2?

★★★★★

1. Читайте спеку.

2. Читайте пункт 1.

Кстати, int i = 0; i = i++; - это первый вопрос на отсев при Жаба-собеседовании тех мальчиков студиоузов-недоучек, которые пишут о двух десятках аббревиатур наикрутейших модных фреймворков в своем CV.

Bioreactor ★★★★★
()

> Так в C ... оно выводит 4

Быдло.

Manhunt ★★★★★
()

Вы упоролись. В стандарте Си (и, наверно, Явы и Плюсов) для таких случаев поведение не определено. Доверять полученному значению нельзя в любом случае. И уж тем более пытаться угадать.

melkor217 ★★★★★
()
Ответ на: Пруфлинка нет. от Camel

> разбор этой штуки как раз по стандарту. Почему в C будет 4 (внимательно изучали указатели)

4.2 По Стандарту это undefined behaviour

Manhunt ★★★★★
()
Ответ на: Пруфлинка нет. от Camel

> Почему в C будет 4 (внимательно изучали указатели)

В Си это никак в спеке не пропейсано. В отличие от Java и шарпея.

внимательно изучали указатели

При чем тут «указатели»??? Неужели сейчас так студентов в институтах АЯП учат?

Что не определено по спеке - то на усмотрение реализатора. Это правило.

Bioreactor ★★★★★
()
Ответ на: комментарий от melkor217

> В стандарте Си (и, наверно, Явы и Плюсов) для таких случаев поведение не определено

4.2. В Джаве это строго определено.

И спрашивается на сертификационном экзамене.

Bioreactor ★★★★★
()
Ответ на: комментарий от melkor217

Пункт 15.15.1 третей редакции спецификации языка Java.

Bioreactor ★★★★★
()
Ответ на: комментарий от KRoN73

>тоже скопилируется. Почему бы и нет? :)
Компилируется, да вот только на разных компиляторах и разных языках (с учётом их синтаксиса) будет одинаковый эффект, а в сабже разный.

Nao ★★★★★
()

Кто там ругался на приоритеты в Perl?

DNA_Seq ★★☆☆☆
()
Ответ на: комментарий от Nao

Ну так если пишешь подобный код то должен представлять в каком порядке переменные кладутся в стек. К тому же применение инкремента в выражении уже попахивает кульцхакерством. И не забываем что в случае указателей прирост инкремента зависит от модели памяти

DNA_Seq ★★☆☆☆
()
Ответ на: комментарий от Deleted

Интересно просто. Я знаю что такое писать нельзя и никогда так не писал.

urxvt ★★★★★
() автор топика
Ответ на: комментарий от Nao

>Компилируется, да вот только на разных компиляторах и разных языках (с учётом их синтаксиса) будет одинаковый эффект, а в сабже разный.

Тогда тем больше повода использовать «goto loop» :)

KRoN73 ★★★★★
()
Ответ на: комментарий от Bioreactor

> В Си это никак в спеке не пропейсано.

4.2

Manhunt ★★★★★
()
Ответ на: комментарий от Bioreactor

> Кстати, int i = 0; i = i++; - это первый вопрос на отсев при Жаба-собеседовании

можно подробнее.

потому что с Си это нормальное поведение

i = 1 будет.

А вот i += i++; - это уже не определено

namezys ★★★★
()
Ответ на: комментарий от namezys

>> int i = 0; i = i++; - это первый вопрос на отсев

с Си это нормальное поведение

i = 1 будет.



Откуда столько быдла-то?
man sequence points
man sequence points
man sequence points

Manhunt ★★★★★
()
Ответ на: комментарий от Manhunt

а по русски.

даже в худшем случае:

i++ - это взять 0, увеличить его на 1, вернуть. Далее может быть внутри оператора присвоение (в i будет положено 1, либо ничего неположенно). Далее будет присвоение 1. Если на прошлом шаге не было туда положено 1, то оно будет положено. И все равно будет 1.

Но по моему ++i и i++ должны завершиться полностью до присвоения

namezys ★★★★
()
Ответ на: комментарий от Manhunt

> Это IT. Стандарт на русский не переведен.

Да не полезу я в стандарт. Либо выдержку, либо оровергнете то, что я написал.

Но я согласен с тем, что это частный случай, в котором просто повезло, что все сработало

namezys ★★★★
()
Ответ на: комментарий от Manhunt

Ладно. Тогда надо идти в стандарт

Но i++ атомарен. Искать в стандартне не буду, но в Си это точно.

Вопрос возникает тогда, когда у нас 2 операции, порядок которых не определне, которые одновремено пишуться и читаються из одной переменной

namezys ★★★★
()
Ответ на: комментарий от Manhunt

Набздел.

разбор этой штуки как раз по стандарту. Почему в C будет 4 (внимательно изучали указатели)

4.2 По Стандарту это undefined behaviour

Да, набздел. Луркмора перечитал.

Camel ★★★★★
()
Ответ на: комментарий от KRoN73

>Для Си порядок вычисления (слева направо или наоборот) не определён.

Определён. С самого начала. По каждому оператору прописан. Для сложения - слева на право.

Вот так -

По стандарту языка C и C++ оператор сложения + не является точкой следования, поэтому в выражении g()+f() возможно, что любая из функций может быть вычислена первой.

- определён?

Xenesz ★★★★
()

> Я тут случайно узнал что следующий код дает разный результат для разных языков. Всю жизнь был уверен что оно работает одинаково кругом, и возвращает 4.

Более того, это UB и каждый компилятор будет выдавать свои варианты.

andreyu ★★★★★
()

все реализации Java (JVM и компилятора) дадут 2?

Там зато есть гарантия гарантии что

Integer i = 4000;
Integer j = 4000;

i == j ;//вернет false

wfrr ★★☆
()

Помню эпичный тред на одном техническом форуме. Обсуждали этот вопрос и спорили на счёт того что логичнее. Вывели с 20 логик, с которыми сложно спорить. Однако везде используют разные.
В таких моментах лучше сразу в спеки смотреть, не иначе.

tia
()
Ответ на: комментарий от KRoN73

Что «ась»? Один из операндов сложения должен вычислиться раньше, а стандарт говорит, что надо бросать жребий, чтобы определить, какой.

Xenesz ★★★★
()
Ответ на: комментарий от Xenesz

И что тогда, по-твоему, обозначает понятие левоассоциативности сложения? И что значит - «порядок вычисления слева на право»?

KRoN73 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.