Когда можно делать / использовать что-то с неопределенным поведением?

В 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";

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

Другие вопросы по тегам