When is it fair to purposefully invoke undefined behavior?

The standard library usually allows undefined behavior if you violate any template type requirements, give erroneous function arguments, or any other violation of contract. Is it good practice to do this in custom libraries? When is it fair?

Consider a operator[]

container entry :

template <typename t>
T& container<T>::operator[](int i)
{
  return internal_array[i];
}

      

If it i

indexes out of bounds internal_array

, we end up in undefined mode. Should we allow this execution, or should we do bounds checking and exception?

Another example is a function that takes an argument int

but only allows a restricted domain:

int foo(int x)
{
  if (x > 0 && x <= 10) {
    return x;
  }
}

      

If x

not in a domain, execution will reach the end of the function without a statement return

- this gives undefined behavior.

Should the library developer feel bad about resolving this or not?

+3


source to share


2 answers


When is it fair to purposefully invoke undefined behavior?

Assuming you are asking this from the perspective of a library developer: whenever you warn your client that not meeting the preconditions of a given function will cause undefined Behavior, and your client breaks those preconditions, conditions.

The C ++ 11 Standard Library defines many such functions: just think of an operator index for collections of sequences.



If you are asking this from the point of view of an application programmer, then, on the other hand, the answer is, of course, "never" unless you write non-portable code that relies on some documented extension of your compiler and / or some of your functions. operating system (but then that proves that you are still "speaking C ++").

Should the library developer feel bad about resolving this or not?

If so, then mr. Now Stepanov should feel terrible. No, that's not bad, it just depends on whether your library is designed for maximum efficiency or maximum security - with a lot of nuances in the middle.

+3


source


It all comes down to documentation.

Intuitively, you didn't expect to do []

bounds checking, but you can also provide a method at

for your container that throws an exception (yay, just like the people who write std

). You can of course throw an exception, but document this behavior.



The second is fair play and as long as you clearly state that the behavior is undefined if the function is called with bad arguments and you have every reason to do so (red). If you are developing a performance-critical library, you do not need the input validation overhead. If not, throw an exception.

+1


source







All Articles