Что именно означают «IB» и «UB»? - PullRequest
102 голосов
/ 04 мая 2010

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

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

Ответы [ 5 ]

127 голосов
/ 04 мая 2010

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

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

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

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

17 голосов
/ 04 мая 2010

Поведение, определяемое реализацией, и Неопределенное поведение

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

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

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

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

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

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

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

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

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

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

4 голосов
/ 13 декабря 2011

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

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

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

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

4 голосов
...