хз, может потому что компилятор оптимизировал это и оно параллельно выполняется? ну а параллельная запись может ломать прогу в таком виде, попробуй атомарный тип использовать. Больше идей пока нет :)
$ cat 1.cc
#include <iostream>
class MyClass {
public:
int v;
MyClass(int v) {
this->v = v;
}
};
int main (void)
{
MyClass a = a = 42;
std::cout << a.v;
return 0;
}
$ g++ -Wall -O2 1.cc
1.cc: В функции «int main()»:
1.cc:14:18: предупреждение: операция над «a» может дать неопределенный результат [-Wsequence-point]
MyClass a = a = 42;
^
1.cc:14:18: предупреждение: операция над «a» может дать неопределенный результат [-Wsequence-point]
$ g++ --version
g++ (GCC) 4.9.1
Просто когда в коде есть «i++ + ++i», то всем пофиг - ибо работает. Потом меняется версия компилятора или ещё чё-нить и возникает такой вопрос: как оно работало?
Вообще есть санитайзеры, да даже clang/gcc с -Wall, -pedantic понаходит такие UB.
А зачем их оправдывать? Это язык, который частично совместим с С, который вырос из него, и который не ломает совместимость при своей эволюции. Все адекватно и логично. Скорее надо оправдывать новые «С++-заменители», которые не могут достойно заменить дедушку с нелегкой судьбой из 80-х.
Так в чем же тут совместимость, если унаследовано UB?
У UB торчат ноги из тех самых 80-х, когда компиляторы не были такими продвинутыми. Кроме того UB (не все, но многие) это просто неотъемлемая часть продвинутых ассемблеров, коими во многом С и С++ и являются, стоит вылезти из уютной песочницы - и они поджидают тебя со всех сторон.
И какой уровень продвинутости компилятора необходим, чтобы запрещать использовать объект в той же sequence point, в которой он инициализируется? Это должно элементарно делаться на уровне резолвинга имён переменных при синтаксическом анализе. (Который Си неотделим от семантического - грамматика не КС.)
И какой уровень продвинутости компилятора необходим, чтобы запрещать использовать объект в той же sequence point, в которой он инициализируется?
В 80-е при борьбе за каждый байт и такт, и при том, что обезьян к программированию допускали меньше, это были вполне допустимые упрощения, чтоб облегчить жизнь авторам компиляторов. Сейчас же никто не мешает взять clang, выставить -Werror, и спокойно заниматься делом. А насчет стандарта - если в С изменят, то и в С++ подхватят, последний не зря так называется.