Как стать автором
Обновить

Комментарии 85

Спрашивайте, критикуйте… :)
>> i = ++i + ++i

на собеседованиях подобные примеры любят задавать. Вот в следующий раз дам ссылку им на эту статью, может быть тогда поймут, и будут просто спрашивать просто, какие у инкремента и декремента.
вот я наговорил… Правильно: будут спрашивать, какие отличия у инкремента и декремента
а-а-а, убейте меня, надо же 2 раза подряд ошибиться :(

Преинкремент и постинкремент.
на собеседованиях спрашивают применительно к конкретному языку
Надо иголки под ногти кто так в реальных проектах пишет.

ЗЫ %)
Пишите — такие вещи всегда интерестны для тех, кому лень разбираться «как всё работает» на самом деле изнутри :). А информация очень полезна для них.
НЛО прилетело и опубликовало эту надпись здесь
Моя Javascript сказал 13, а питон — таки да, 10… Теперь они не захотят больше работать вместе)
На Java 13.

Но проблема немного надуманная и очень редко встречается с реальных проектах, а если и встречается, то легко обходится другими способами.
НЛО прилетело и опубликовало эту надпись здесь
Главное — это сразу забыть! :)
никогда бы не подумал так извращаться с инкрементированием.
Головная боль от таких выражений кончается после прочтения стандарта и уяснения что такое sequence points (кажется глава 5 в стандарте C++). Копать асм занятно, но не имеет особого смысла, стандарт дает это на откуп создателям компилятора.
Спасибо за наводку, добавил ссылку на Википедию.
С скомпиленный в gcc:
14
Изящно проблема решена в Ruby :)
Ruby has no pre/post increment/decrement operator. For instance, x++ or x-- will fail to parse. More importantly, ++x or --x will do nothing! In fact, they behave as multiple unary prefix operators: -x == ---x == -----x ==… To increment a number, simply write x += 1.
Нет оператора — нет проблемы :)

Отличное решение
Мне в этом плане больше импонирует Хаскель. Нет переменных — нет проблем.
Да и отладчик там Хаскеле не нужен, не говоря о дизассемблере.
в руби эта проблема решена созданием методов times, upto, downto, each
необходимость в инкременте/декременте просто отпадает
Инкремент/декремент нужен не только в циклах :)
само собой)
но изменение счетчика цикла — один из наиболее популярных случаев его использования
x += 1 работает и в Си и в Яве. Но он не возвращает значение. К примеру, написать a = x++ можно, а написать a = x += 1 — нельзя.
В перле можно :)
Не уверен про java, но в си, конечно же, возвращает :) и a = x += 1 — вполне законная конструкция
Каюсь, не знал :) Однако ни в Руби, ни в Пайтоне такого всё равно делать нельзя, увы :)
Очень интересно. С чего это вы взяли, будто a = x += 1 в Руби вне закона? Очень даже в.
irb(main):001:0> a=0
=> 0
irb(main):002:0> x=1
=> 1
irb(main):003:0> a = x +=1
=> 2
irb(main):004:0> a
=> 2
irb(main):005:0> x=1
=> 1
irb(main):006:0> a=0
=> 0
irb(main):007:0> a = x +=1 + x +=1
=> 4

p.s.
на лурке про это статья есть
цепное присвоение, на сколько мне известно, доступно почти во всех языках
Питон себя ведет абсолютно также. Так что автору стоит подправить UPD.
В gcc подобное выражение может принимать разные значения в зависимости от разных параметров (например при -O2 и -O3 может быть разный ответ). Штука кстати известная, соль её в том что нельзя изменять параметр более одного раза между двумя точками следования.
Я думаю что использование volatile тоже может повлиять ;)
Ха, а в с++ просто в стандарте сказанно, что модификация переменной между двумя точками следования есть undefined behavior, поэтому смотрение ассемблерного кода — становиться бессмысленным.

Но ведь интересно же! :)
Вроде бы не undefined, а unspecified. То есть, ничего страшного произойти не должно — компилятор всего лишь может по-разному интерпретировать код.
Именно undefined.
Unspecified будет в случае функции inc(int &x) { ++x; }
Порядок вызова функций произвольный, но sequence points добавлены, поэтому unspecified.
python — 10
— #!/usr/bin/env python

i = 5
i = ++i + ++i
print i
потому что в пейтоне нет инкремента
--Кэп
i = 5
i = +--+++--+i +--+++--+i
print i

выводит 10!
Очевидно, поведение Python в этом контексте совпадает с поведением Ruby о котором написано чуть выше: habrahabr.ru/blogs/crazydev/88185/#comment_2643715
в данном случае, вместо инкремента или декремента происходит установка знака у числа. //KO
Если у вас будет время, напишите пожалуйста еще подобных статей. Было интересно)
Спасибо, постараюсь ;)
НЛО прилетело и опубликовало эту надпись здесь
а что поганого? Правильный ответ ведь есть. Он не в числовой форме, но есть.
НЛО прилетело и опубликовало эту надпись здесь
Правильный ответ всё-таки — поведение неопределено :). Про «я бы увольнял» ответить может кандидат на должность, которая предполагает, что он будет наделён полномочиями увольнения сотрудников, но для такой вакансии это более чем странный вопрос :).
А HR же откуда-то получает эту бумажку? Наверное, от технических специалистов этой фирмы. Причём не самого нижнего уровня. А, скорее всего, от будущего непосредственного начальника этого кандидата или сотрудника того же уровня, что вакансия. И если начальник или признаный технический специалист этой конторы считает, что там именно 12-13-14, то это ведь такой своеобразный тест на адекватность этого начальника и конторы, не правда ли? :) Так что всё в порядке с этим тестом :).
НЛО прилетело и опубликовало эту надпись здесь
Да, я именно это и имел в виду под тестом на адекватность.
В TCL нет оператора ++i, но есть аналог i++. Результат вполне логичен:
set i 5
puts [expr [incr i]+[incr i]]

13
Спасибо! Пиши ещё!=)
В копилку информации, аналогично на PL/SQL в Oracle10:
declare
 i number;
begin
 i:=5;
 dbms_output.put_line(i++ + i++ );
end;



Результат 10. Но только потому, что в PL/SQL нет инкремента. Странно что на синтаксис не ругается. На i++ ругается, т.к. ожидалось увидеть второе слагаемое.
В предыдущем комменте должны были быть ++i, но случайно захватил исправленный блок кода.
А можно, ради чистоты эксперимента, тоже самое но с префиксной записью?
declare
i number;
begin
i:=5;
dbms_output.put_line(++i + ++i);
end;



Результат 10. Повторюсь, в PL/SQL нет инкремента — это результат сложения.
Не совсем в тему, но мне показалось удивительным (раз уж разговор зашел про СУБД):

mysql> select -------------1 xx;
+----+
| xx |
+----+
| -1 |
+----+
1 row in set (0.00 sec)
Нечетное число (в вашем примере 13) унарных минусов, что вас смущает?
А то, что --, как и в Oracle, обозначает начало однострочного комментария.
Попробуйте, например, mysql> select ------- ------1 xx;
Это надо в БНФ нотацию языка смотреть и токенайзер.
В MySQL комментарий, о котором вы говорите, это не просто два минуса, а еще и символ пробела за ним — "-- ".
perl: 13
#!/usr/bin/perl -w
my $i=5;
$i = ++$i + $i++;
print $i;
А можно тоже, но с двумя префиксными инкрементами как в посте?
14 получится, только что проверил
Спасибо, обновил цифру в посте.
Да, 14
интересно, кто такой говнокод применяет? даже для си все зависит от компилятора
А каким будет результат в твоем, %username%, компиляторе?

$ kpp -e test.kpp
14

$ cat test.kpp
export function main() {
   var i = 5;
   printf("%d\n", ++i + ++i);
}

$ cat test.gide
use "gbc:diss:/lib/kpp.gbc"

const $$0, std/int, "5"
const $$1, std/string, "%d\n"

function main
   new $0, std/int
   call $0, =, $$0
   mov i$0, $0

   call i$0, ++=
   mov $0, @result
   call i$0, ++=
   call $0, +, @result
   mov $1, @result
   call 0, kpp/printf, $$1, $1
end


P.S: Можно было бы еще написать про то, что если строка записана как «++i+++i», то приоритет операторов тоже может оказать свое влияние.
Простите, а как называется этот язык? )
мой компилятор такое не позволяет писать
www.isdelphidead.com
тогда уж и 4 8 15 16 23 42 ;)
var i:Number = 5;
i = ++i + ++i;
trace(i); // результат 13
Actionscript 3 (MXMLC/flex 4) flashplayer 10.
Спасибо за статью. В следующий раз хотелось бы чего-то более прикладного.
javascript:

var i = 5;
i = ++i + ++i;
alert(i);


результат: 13
bash — 12.
если мыслить логически то 13 правильный ответ.
Все зависит от языка. Например, если мне не изменяет память (я могу ошибаться), в С первыми выполняются унарные операции, то есть инкремент в данном случае. И логичным выглядит ответ 14 (два раза увеличить и сложить).
НЛО прилетело и опубликовало эту надпись здесь
Считаю неправильно жертвовать супероптимизаций в ущерб читаемости кода.
Кроме того желательно, чтобы код алгоритмов при переносе не только между компиляторами, но и похожими языками выдавал один и тот же прогнозируемый результат.
На руби можно попробовать так:

irb(main):001:0> i = 5
=> 5
irb(main):002:0> (i += 1) + (i += 1)
=> 13
Обработка в браузерах
i = 0;
res = ++i + ++i + ++i + ++i; //4 раза

Chrome, Firefox, IE8, Safari: 10
Opera (по крайней мере 11.01 b1190): 32
И это явно глюк, т.к. при сумме 3-х инкрементов Опера дает аналогично другим браузерам 6, а выше — начинает выдавать странное.
>Обработка в браузерах
в смысле клиентский JavaScript
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации