Комментарии 85
Спрашивайте, критикуйте… :)
+9
Пишите — такие вещи всегда интерестны для тех, кому лень разбираться «как всё работает» на самом деле изнутри :). А информация очень полезна для них.
+7
НЛО прилетело и опубликовало эту надпись здесь
Напомнило как 3 года назад мы разбирали случай ++i + i++
gameworld.com.ua/showthread.php/161-disasm-vs-C-disasm
а вообще таких конструкций в коде я стараюсь избегать
gameworld.com.ua/showthread.php/161-disasm-vs-C-disasm
а вообще таких конструкций в коде я стараюсь избегать
+2
На Java 13.
Но проблема немного надуманная и очень редко встречается с реальных проектах, а если и встречается, то легко обходится другими способами.
Но проблема немного надуманная и очень редко встречается с реальных проектах, а если и встречается, то легко обходится другими способами.
+4
НЛО прилетело и опубликовало эту надпись здесь
никогда бы не подумал так извращаться с инкрементированием.
+10
Головная боль от таких выражений кончается после прочтения стандарта и уяснения что такое sequence points (кажется глава 5 в стандарте C++). Копать асм занятно, но не имеет особого смысла, стандарт дает это на откуп создателям компилятора.
+8
С скомпиленный в gcc:
14
14
+1
Изящно проблема решена в 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.
+5
Нет оператора — нет проблемы :)
Отличное решение
Отличное решение
+10
в руби эта проблема решена созданием методов times, upto, downto, each
необходимость в инкременте/декременте просто отпадает
необходимость в инкременте/декременте просто отпадает
0
x += 1 работает и в Си и в Яве. Но он не возвращает значение. К примеру, написать a = x++ можно, а написать a = x += 1 — нельзя.
0
В перле можно :)
+2
Не уверен про java, но в си, конечно же, возвращает :) и a = x += 1 — вполне законная конструкция
+2
Каюсь, не знал :) Однако ни в Руби, ни в Пайтоне такого всё равно делать нельзя, увы :)
0
Очень интересно. С чего это вы взяли, будто a = x += 1 в Руби вне закона? Очень даже в.
0
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.
на лурке про это статья есть
=> 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.
на лурке про это статья есть
0
цепное присвоение, на сколько мне известно, доступно почти во всех языках
0
Питон себя ведет абсолютно также. Так что автору стоит подправить UPD.
0
В gcc подобное выражение может принимать разные значения в зависимости от разных параметров (например при -O2 и -O3 может быть разный ответ). Штука кстати известная, соль её в том что нельзя изменять параметр более одного раза между двумя точками следования.
+2
Ха, а в с++ просто в стандарте сказанно, что модификация переменной между двумя точками следования есть undefined behavior, поэтому смотрение ассемблерного кода — становиться бессмысленным.
+5
Но ведь интересно же! :)
+2
Вроде бы не undefined, а unspecified. То есть, ничего страшного произойти не должно — компилятор всего лишь может по-разному интерпретировать код.
0
Именно undefined.
Unspecified будет в случае функции inc(int &x) { ++x; }
Порядок вызова функций произвольный, но sequence points добавлены, поэтому unspecified.
Unspecified будет в случае функции inc(int &x) { ++x; }
Порядок вызова функций произвольный, но sequence points добавлены, поэтому unspecified.
+1
Вот, нашел интересную блогозапись по теме:
Разница между unspecified behavior и undefined behavior
Разница между unspecified behavior и undefined behavior
+2
Угу, там еще рядом как раз про точки следования:
alenacpp.blogspot.com/2005/11/sequence-points.html
alenacpp.blogspot.com/2005/11/sequence-points.html
+1
python — 10
— #!/usr/bin/env python
i = 5
i = ++i + ++i
print i
— #!/usr/bin/env python
i = 5
i = ++i + ++i
print i
+1
потому что в пейтоне нет инкремента
--Кэп
--Кэп
+6
i = 5
i = +--+++--+i +--+++--+i
print i
выводит 10!
-1
Очевидно, поведение Python в этом контексте совпадает с поведением Ruby о котором написано чуть выше: habrahabr.ru/blogs/crazydev/88185/#comment_2643715
0
в данном случае, вместо инкремента или декремента происходит установка знака у числа. //KO
0
Если у вас будет время, напишите пожалуйста еще подобных статей. Было интересно)
+2
НЛО прилетело и опубликовало эту надпись здесь
а что поганого? Правильный ответ ведь есть. Он не в числовой форме, но есть.
0
НЛО прилетело и опубликовало эту надпись здесь
Правильный ответ всё-таки — поведение неопределено :). Про «я бы увольнял» ответить может кандидат на должность, которая предполагает, что он будет наделён полномочиями увольнения сотрудников, но для такой вакансии это более чем странный вопрос :).
А HR же откуда-то получает эту бумажку? Наверное, от технических специалистов этой фирмы. Причём не самого нижнего уровня. А, скорее всего, от будущего непосредственного начальника этого кандидата или сотрудника того же уровня, что вакансия. И если начальник или признаный технический специалист этой конторы считает, что там именно 12-13-14, то это ведь такой своеобразный тест на адекватность этого начальника и конторы, не правда ли? :) Так что всё в порядке с этим тестом :).
А HR же откуда-то получает эту бумажку? Наверное, от технических специалистов этой фирмы. Причём не самого нижнего уровня. А, скорее всего, от будущего непосредственного начальника этого кандидата или сотрудника того же уровня, что вакансия. И если начальник или признаный технический специалист этой конторы считает, что там именно 12-13-14, то это ведь такой своеобразный тест на адекватность этого начальника и конторы, не правда ли? :) Так что всё в порядке с этим тестом :).
0
В TCL нет оператора ++i, но есть аналог i++. Результат вполне логичен:
13
set i 5
puts [expr [incr i]+[incr i]]
13
+1
Спасибо! Пиши ещё!=)
+1
В копилку информации, аналогично на PL/SQL в Oracle10:
Результат 10. Но только потому, что в PL/SQL нет инкремента. Странно что на синтаксис не ругается. На i++ ругается, т.к. ожидалось увидеть второе слагаемое.
declare
i number;
begin
i:=5;
dbms_output.put_line(i++ + i++ );
end;
Результат 10. Но только потому, что в PL/SQL нет инкремента. Странно что на синтаксис не ругается. На i++ ругается, т.к. ожидалось увидеть второе слагаемое.
-1
В предыдущем комменте должны были быть ++i, но случайно захватил исправленный блок кода.
0
А можно, ради чистоты эксперимента, тоже самое но с префиксной записью?
0
declare
i number;
begin
i:=5;
dbms_output.put_line(++i + ++i);
end;
Результат 10. Повторюсь, в PL/SQL нет инкремента — это результат сложения.
+2
Не совсем в тему, но мне показалось удивительным (раз уж разговор зашел про СУБД):
mysql> select -------------1 xx;
+----+
| xx |
+----+
| -1 |
+----+
1 row in set (0.00 sec)
0
Нечетное число (в вашем примере 13) унарных минусов, что вас смущает?
0
А то, что
Попробуйте, например,
--
, как и в Oracle, обозначает начало однострочного комментария.Попробуйте, например,
mysql> select ------- ------1 xx;
-1
Это надо в БНФ нотацию языка смотреть и токенайзер.
0
В MySQL комментарий, о котором вы говорите, это не просто два минуса, а еще и символ пробела за ним — "
--
".+3
perl: 13
#!/usr/bin/perl -w
my $i=5;
$i = ++$i + $i++;
print $i;
#!/usr/bin/perl -w
my $i=5;
$i = ++$i + $i++;
print $i;
+1
интересно, кто такой говнокод применяет? даже для си все зависит от компилятора
-2
А каким будет результат в твоем, %username%, компиляторе?
P.S: Можно было бы еще написать про то, что если строка записана как «++i+++i», то приоритет операторов тоже может оказать свое влияние.
$ 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», то приоритет операторов тоже может оказать свое влияние.
+2
Простите, а как называется этот язык? )
+1
man.deeptown.org/index.php/K++ Не пиара ради :)
+1
мой компилятор такое не позволяет писать
www.isdelphidead.com
www.isdelphidead.com
+1
42
+2
var i:Number = 5;
i = ++i + ++i;
trace(i); // результат 13
Actionscript 3 (MXMLC/flex 4) flashplayer 10.
i = ++i + ++i;
trace(i); // результат 13
Actionscript 3 (MXMLC/flex 4) flashplayer 10.
0
Спасибо за статью. В следующий раз хотелось бы чего-то более прикладного.
+1
javascript:
результат: 13
var i = 5;
i = ++i + ++i;
alert(i);
результат: 13
+1
bash — 12.
если мыслить логически то 13 правильный ответ.
если мыслить логически то 13 правильный ответ.
+3
НЛО прилетело и опубликовало эту надпись здесь
Считаю неправильно жертвовать супероптимизаций в ущерб читаемости кода.
Кроме того желательно, чтобы код алгоритмов при переносе не только между компиляторами, но и похожими языками выдавал один и тот же прогнозируемый результат.
Кроме того желательно, чтобы код алгоритмов при переносе не только между компиляторами, но и похожими языками выдавал один и тот же прогнозируемый результат.
+1
На руби можно попробовать так:
irb(main):001:0> i = 5
=> 5
irb(main):002:0> (i += 1) + (i += 1)
=> 13
irb(main):001:0> i = 5
=> 5
irb(main):002:0> (i += 1) + (i += 1)
=> 13
+1
Обработка в браузерах
Chrome, Firefox, IE8, Safari: 10
Opera (по крайней мере 11.01 b1190): 32
И это явно глюк, т.к. при сумме 3-х инкрементов Опера дает аналогично другим браузерам 6, а выше — начинает выдавать странное.
i = 0;
res = ++i + ++i + ++i + ++i; //4 раза
Chrome, Firefox, IE8, Safari: 10
Opera (по крайней мере 11.01 b1190): 32
И это явно глюк, т.к. при сумме 3-х инкрементов Опера дает аналогично другим браузерам 6, а выше — начинает выдавать странное.
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Все знают что "++i + ++i" — плохо, но что-же за ширмой?