- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
void iseq(int a, int b){ assert(a==b); }
void ismt(int a, int b){ assert(a+1==b); }
int main(int argc, char **argv){
{ int j=100, *jp; jp=&argc; iseq(j++, j); assert(j==101); } //100, 100
{ int j=100, *jp; iseq(j++, j); jp=&j; assert(j==101); } //100, 100
{ int j=100, *jp; iseq(j++, j); assert(&j && j==101); } //100, 100
{ int j=100, *jp; ismt(j++, j); assert(j==101); } //100, 100
{ int j=100, *jp; jp=&j; printf("\n%d, %d\n", j++, j); assert(j==101); } //100, 100
{ int j=100, *jp; printf("%d, %d\n", j++, j); jp=&j; assert(j==101); } //100, 100
{ int j=100, *jp; printf("%d, %d\n", j++, j); assert(&j && j==101); } //100, 100
{ int j=100; printf("%d, %d\n", j++, j); assert(j==101); } //100, 101
{ int j=100, *jp; jp=&j; printf("\n%d, %d\n", ++j, j); assert(j==101); } //101, 100
{ int j=100, *jp; printf("%d, %d\n", ++j, j); jp=&j; assert(j==101); } //101, 100
{ int j=100; printf("%d, %d\n", ++j, j); assert(j==101); } //101, 101
return 0;
}
Кто нибудь знает почему ЭТО работает так? Проверял на нескольких компиляторах везде такой эффект.
laMer007 31.10.2016 09:12 # 0
guest 04.11.2016 01:03 # 0
bormand 04.11.2016 06:53 # 0
Когда адрес переменной не нужен - конпелятор может засунуть переменную в регистр и даже не выделять под неё память. Когда берёшь адрес - волей-неволей приходится юзать настоящую переменную. Вот тебе и другие оптимизации с другим поведением.
З.Ы. И если ты поюзал что-то, что в стандарте обозначено как undefined (а порядок вычисления аргументов как раз таки не определён) - на результат даже фаза луны влиять будет, не то что взятие адреса...
huesto 31.10.2016 09:28 # +7
3_dar 31.10.2016 17:46 # 0
huesto 31.10.2016 18:11 # +6
Ты знал, что make_shared сделали не только для оптимизации пирфоманса? Вызов
может течь, если bar() бросает исключения. Потому что код может выполняться в последовательности 1) new 5; 2) bar(); 3) std::shared_ptr(...).
3_dar 31.10.2016 19:23 # +1
Но при чем здесь shared_ptr? я не знаю что это
Ответа foo(koko(bar()), baz()) вполне достаточно.
huesto 31.10.2016 19:33 # +2
4e1 31.10.2016 21:43 # 0
не совсем
память выделенная на стеке, освободится в том числе в случае исключения, но в примере с shared_ptr - память выделяется через new в куче, её нужно освобождать через delete, это должен сделать сам shared_ptr, но из-за исключения до него дело не дойдёт.
Antervis 01.11.2016 06:00 # 0
huesto 31.10.2016 11:00 # +1
http://coliru.stacked-crooked.com/a/3b10ae5964ab8cc2
http://coliru.stacked-crooked.com/a/3251602c5a8a92e8
Обрати внимание, как шланг без всяких флагов сообщил, что в коде баг.
guest 04.11.2016 03:15 # 0
У gcc как оказалось это предупреждение по умолчанию выключено. С "-Wall" он выдал такие же предупреждения что и clang.
bormand 04.11.2016 06:57 # 0
huesto 04.11.2016 13:20 # +1
barop 05.11.2016 02:12 # −63
4e1 31.10.2016 11:27 # +6
g: sequence point
inkanus-gray 31.10.2016 17:58 # +1
huesto 31.10.2016 18:13 # 0
Soul_re@ver 31.10.2016 21:37 # 0
barop 06.11.2016 20:35 # −63
gost 31.10.2016 21:32 # +2
А ведь уже несколько поколений сишников и крестовиков сталкиваются с подобными UB! Так и представляю картину - камин, кресло-качалка, в нём сидит дедушка и внуку рассказывает: "А вот как-то кодил я на плюсах, да угораздило-ж меня два инкремента в одну точку следования всунуть!..".
inkanus-gray 31.10.2016 22:45 # +2
Можно найти условия, при которых и один инкремент сглючит. Надо всего лишь в том же выражении использовать ту же переменную ещё раз.
Преинкремент по идее должен быть менее коварным, чем постинкремент, но оптимизация может помочь испортить и его.
huesto 31.10.2016 22:49 # +4
XEP 31.10.2016 21:55 # −5
BCEM_noxyu 07.11.2016 23:54 # 0