Когда можно делать / использовать что-то с неопределенным поведением?
В C++ есть вещи, которые находятся где-то между четко определенными и неопределенными. В частности, они называются реализацией определенной и неопределенной. Прямо сейчас я интересуюсь неуказанными вещами.
Когда можно использовать такие функции и когда их следует избегать? Есть ли хорошие примеры неуказанного поведения, являющегося частью правильного кода? Когда, если вообще, это лучший выбор при написании программного обеспечения?
Определения, предоставленные Мэттом МакНаббом:
Не определено - все может произойти
Определяется реализацией - возможно конечное число результатов, и в документации компилятора должно быть указано, что происходит
Не указано - возможно конечное число результатов - обычно Стандарт описывает набор возможных результатов
Четко определено - ничего из вышеперечисленного
Правильно сформированная программа - программа, которая компилируется без ошибок (может проявлять неопределенное поведение)
Дополнительный вопрос:
Расслабленная атомика считается неопределенной или четко определенной?
Помечено как дубликат вопроса, в котором говорится об одной и той же идее с другой точки зрения. Вопрос, помеченный как тот же, говорит об определении неопределенного поведения, тогда как здесь вопрос о том, как и когда его использовать.
1 ответ
Чтобы ответить на новый вопрос: "Когда можно использовать неопределенное поведение?"
Это может звучать немного шутливо, но "в любое время вам не важно, какой вариант произойдет".
Например,
int foo() { cout << "foo"; return 1; }
int bar() { cout << "bar"; return 2; }
// ...
cout << (foo() + bar()) << "\n";
Если вам все равно, видите ли вы "foobar3" или "barfoo3", вы можете написать этот код. Если это имеет значение, то вам придется изменить его, например,
int i = foo(); i += bar(); cout << i << "\n";
Порядок не указан, так как хорошо, чтобы компилятор мог свободно выбирать, какой порядок является оптимальным, в более общем случае.