What exactly do "IB" and "UB" mean?

C++TerminologyDefinition

C++ Problem Overview


I've seen the terms "IB" and "UB" used several times, particularly in the context of C++. I've tried googling them, but apparently those two-letter combinations see a lot of use. :P

So, I ask you...what do they mean, when they're said as if they're a bad thing?

C++ Solutions


Solution 1 - C++

IB: Implementation-defined Behaviour. The standard leaves it up to the particular compiler/platform to define the precise behaviour, but requires that it be defined.

Using implementation-defined behaviour can be useful, but makes your code less portable.

UB: Undefined Behaviour. The standard does not specify how a program invoking undefined behaviour should behave. Also known as "nasal demons" because theoretically it could make demons fly out of your nose.

Using undefined behaviour is nearly always a bad idea. Even if it seems to work sometimes, any change to environment, compiler or platform can randomly break your code.

Solution 2 - C++

Implementation-defined behavior and Undefined behavior

The C++ standard is very specific about the effects of various constructs, and in particular you should always be aware of these categories of trouble:

  • Undefined behavior means that there are absolutely no guarantees given. The code could work, or it could set fire to your harddrive or make demons fly out your nose. As far as the C++ language is concerned, absolutely anything might happen. In practical terms, this generally means that you have an unrecoverable bug. If this happens, you can't really trust anything about your application (because one of the effects of this undefined behavior might just have been to mess up the memory used by the rest of your app). It's not required to be consistent, so running the program twice might give different results. It may depend on the phases of the moon, the color of the shirt you're wearing, or absolutely anything else.

  • Unspecified behavior means that the program must do something sane and consistent, but it is not required to document this.

  • Implementation-defined behavior is similar to unspecified, but must also be documented by the compiler writers. An example of this is the result of a reinterpret_cast. usually, it simply changes the type of a pointer, without modifying the address, but the mapping is actually implementation-defined, so a compiler could map to a completely different address, as long as it documented this choice. Another example is the size of an int. The C++ standard doesn't care if it is 2, 4 or 8 bytes, but it must be documented by the compiler

But common for all of these is that they're best avoided. When possible, stick with behavior that is 100% specified by the C++ standard itself. That way, you're guaranteed portability.

You often have to rely on some implementation-defined behavior as well. It may be unavoidable, but you should still pay attention to it, and be aware that you're relying on something that may change between different compilers.

Undefined behavior, on the other hand, should always be avoided. In general, you should just assume that it makes your program explode in one way or another.

Solution 3 - C++

  • IB: is implementation defined behavior - the compiler must document what it does. Performing a >> operation on a negative value is an example.

  • UB: undefined behavior - the compiler can do what ever, including simply crashing or giving unpredictable results. Dereferencing a null pointer falls into this category, but also subtler things like pointer arithmetic that falls outside the bounds of an array object.

Another related term is 'unspecified behavior'. This is kind of between implementation defined and undefined behaviors. for unspecified behavior, the compiler must do something according to the standard, but exactly which choices the standard gives it is up to the compiler and need not be defined (or even consistent). Things like order of evaluation of sub-expressions falls in this category. The compiler can perform these in whatever order it likes, and could do it differently in different builds or even in different runs of the same build (unlikely, but permitted).

Solution 4 - C++

Solution 5 - C++

The short version:

Implementation-defined behaviour (IB): Correctly programmed but indeterminate*

Undefined behaviour (UB): Incorrectly programmed (i.e. a bug!)

*) "indeterminate" as far as the language standard is concerned, it will of course be determinate on any fixed platform.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioncHaoView Question on Stackoverflow
Solution 1 - C++ThomasView Answer on Stackoverflow
Solution 2 - C++jalfView Answer on Stackoverflow
Solution 3 - C++Michael BurrView Answer on Stackoverflow
Solution 4 - C++missingfaktorView Answer on Stackoverflow
Solution 5 - C++Kerrek SBView Answer on Stackoverflow