Что именно означают" IB "и" UB"?

Я видел термины "IB" и "UB", используемые несколько раз, особенно в контексте C++. Я пробовал их гуглить, но, по-видимому, эти двухбуквенные комбинации видят много пользы. : P

Итак, я спрашиваю вас...что они имеют в виду, когда говорят, что они плохие?

5 ответов


IB: поведение, определяемое реализацией. стандарт оставляет его до конкретного компилятора / платформы для определения точного поведения, но требует, чтобы он был определен.

использование поведения, определенного реализацией, может быть полезно, но делает ваш код менее переносимым.

UB: неопределенное поведение. стандарт не указывает, как должна вести себя программа, вызывающая неопределенное поведение. Также известный как "носовые демоны", потому что теоретически это может заставить демонов вылететь из твоего носа.

использование неопределенного поведения почти всегда является плохой идеей. Даже если это иногда работает, любое изменение среды, компилятора или платформы может случайно сломать ваш код.


реализация-определенное поведение и неопределенное поведение

стандарт C++ очень специфичен в отношении эффектов различных конструкций, и, в частности, вы всегда должны знать об этих категориях проблемы:

  • неопределенное поведение означает, что нет абсолютно никакой гарантии. Код может работать, или он может поджечь ваш жесткий диск или заставьте демонов вылететь из вашего носа. Насколько язык C++ беспокоит, абсолютно все может случиться. На практике это обычно означает, что у вас есть неисправимая ошибка. Если это произойдет, вы не можете действительно доверять что-нибудь о вашем приложении (потому что одним из эффектов этого неопределенного поведения может быть просто испортить память, используемую остальной частью вашего приложения). Это не обязательно должно быть согласованным, поэтому запуск программы дважды может дать разные результаты. Это может зависеть от фаз луны, цвета рубашки ты одета или что-то еще.

  • неопределенное поведение означает, что программа должна делать что-то разумное и последовательное, но это не требуется документ этого.

  • поведение, определяемое реализацией, похоже на неуказанное, но также должно быть задокументировано авторами компилятора. Примером этого является результат reinterpret_cast. обычно, он просто изменяет тип указателя, без изменения адрес, но сопоставление фактически определяется реализацией, поэтому компилятор может карта на совершенно другой адрес, если он задокументировал этот выбор. Другим примером является размер int. Стандарт C++ не заботится, если это 2, 4 или 8 байт, но это должны подтверждается компилятор

но общим для всех них является то, что они лучше избегать. Когда это возможно, придерживайтесь поведения, которое на 100% определено C++ сам стандарт. Таким образом, вам гарантирована переносимость.

вам часто приходится полагаться на определенное реализацией поведение. Это может быть неизбежно, но вы все равно должны обратить на это внимание и знать, что вы полагаетесь на то, что может измениться между разными компиляторами.

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


  • IB: определяется ли реализация поведения-компилятор должен документировать, что он делает. Выполняя >> операция с отрицательным значением является примером.

  • UB: неопределенное поведение - компилятор может делать все, что угодно, включая просто сбой или непредсказуемые результаты. Разыменование нулевого указателя попадает в эту категорию, но также и более тонкие вещи, такие как арифметика указателя, которая выходит за пределы массива объект.

другой связанный термин - "неопределенное поведение". Это между определенным и неопределенным поведением. для неопределенного поведения компилятор должен делать что-то в соответствии со стандартом, но точно, какой выбор дает стандарт, зависит от компилятора и не должен быть определен (или даже согласован). Такие вещи, как порядок оценки под-выражений, попадают в эту категорию. Компилятор может выполнять их в любом порядке, и может делать это по-разному в разных сборках или даже в разных запусках одной и той же сборки (маловероятно, но возможно).



краткая версия:

поведение, определяемое реализацией (IB): правильно запрограммировано, но неопределенно*

неопределенное поведение (UB): неправильно запрограммировано (т. е. a ошибка!)

*) "неопределенный", что касается языкового стандарта, он, конечно, будет определяться на любой фиксированной платформе.