Я видел несколько терминов "IB" и "UB", особенно в контексте С++. Я пробовал их искать, но, похоже, эти двухбуквенные комбинации очень полезны.: P
Итак, я спрашиваю вас... что они означают, когда говорят, что они плохие?
Я видел несколько терминов "IB" и "UB", особенно в контексте С++. Я пробовал их искать, но, похоже, эти двухбуквенные комбинации очень полезны.: P
Итак, я спрашиваю вас... что они означают, когда говорят, что они плохие?
IB: поведение, определяемое реализацией. Стандарт оставляет его конкретному компилятору/платформе для определения точного поведения, но требует, чтобы он был определен.
Использование определенного для реализации поведения может быть полезным, но делает ваш код менее портативным.
поведение UB: Undefined. В стандарте не указывается, как поведение программы, вызывающее поведение Undefined, должно вести себя. Также известен как "носовые демоны", потому что теоретически это может заставить демонов вылететь из вашего носа.
Использование поведения Undefined - почти всегда плохая идея. Даже если это работает иногда, любые изменения в среде, компиляторе или платформе могут случайно разбивать ваш код.
Поведение при реализации и поведение Undefined
Стандарт С++ очень специфичен в отношении эффектов различных конструкций, и в частности вы всегда должны знать об этих категориях проблем:
Undefined поведение означает, что нет никаких гарантий. Код может работать, или он может поджечь ваш жесткий диск или заставить демонов вылететь из вашего носа. Что касается языка С++, абсолютно все может случиться. На практике это обычно означает, что у вас есть неустранимая ошибка. Если это произойдет, вы не можете действительно доверять чему-либо в своем приложении (поскольку одним из эффектов этого поведения Undefined могло быть просто испорчение памяти, используемой остальной частью вашего приложения). Это не обязано быть последовательным, поэтому запуск программы дважды может дать разные результаты. Это может зависеть от фаз луны, цвета рубашки, которую вы носите, или абсолютно ничего другого.
Неопределенное поведение означает, что программа должна делать что-то разумное и последовательное, но не обязательно документировать это.
Поведение, определяемое реализацией, похоже на неуказанное, но должно также быть документировано авторами компилятора. Примером этого является результат reinterpret_cast
. обычно он просто меняет тип указателя, не изменяя адрес, но отображение на самом деле определяется реализацией, поэтому компилятор может отображать совершенно другой адрес, если он задокументировал этот выбор. Другим примером является размер int. Стандарту С++ все равно, если это 2, 4 или 8 байтов, но он должен быть документирован компилятором
Но общим для всех является то, что их лучше избегать. Когда это возможно, придерживайтесь поведения, которое на 100% определяется самим стандартом С++. Таким образом, вам гарантирована мобильность.
Вам часто приходится полагаться на некоторое поведение, определенное реализацией. Это может быть неизбежно, но вы все равно должны обратить на это внимание и быть в курсе, что вы полагаетесь на то, что может измениться между разными компиляторами.
С другой стороны, поведениеUndefined должно избегать всегда. В общем, вы должны просто предположить, что это заставляет вашу программу взорваться так или иначе.
IB: это определенное поведение при реализации - компилятор должен документировать, что он делает. Выполнение операции >>
с отрицательным значением является примером.
UB: поведение undefined - компилятор может делать все, что угодно, включая просто сбой или непредсказуемые результаты. Разделение нулевого указателя попадает в эту категорию, но также и более тонкие вещи, такие как арифметика указателя, которая выходит за пределы объекта массива.
Другим родственным термином является "неопределенное поведение". Это отчасти зависит от реализации и поведения undefined. для неуказанного поведения компилятор должен что-то делать в соответствии со стандартом, но именно тот вариант, который он дает стандарту, зависит от компилятора и его не нужно определять (или даже согласовывать). В эту категорию попадают такие вещи, как порядок оценки подвыражений. Компилятор может выполнять их в любом порядке, который ему нравится, и мог бы делать это по-разному в разных сборках или даже в разных прогонах одной и той же сборки (маловероятно, но разрешено).
Краткая версия:
Реализованное поведение (IB): Правильно запрограммированное, но неопределенное *
Undefined поведение (UB): Неправильно запрограммировано (т.е. ошибка!)
*) "undefined" в отношении стандарта языка, он, конечно, будет определен на любой фиксированной платформе.