What is the difference between undefined behavior , unspecified behavior and implementation-defined behavior ?

    2 answers 2

    undefined behavior - undefined behavior. Behavior to which the standard language does not impose any requirements. Undefined behavior can be expected when no explicit behavior is specified or when the program uses erroneous constructions or data. The permissible response to undefined behavior can vary from completely ignoring the situation with unpredictable results to normal behavior during a broadcast or program execution in accordance with the expected behavior of the environment (with or without output of diagnostic messages), or until the broadcast or program execution stops (with a diagnostic message ). Many erroneous program constructions do not lead to indefinite behavior, but require the output of appropriate diagnostic messages.

    Examples of undefined behavior:

    • access to array elements outside the allowed bounds . For example, 5 elements are highlighted, and we are trying to read an element with an index> = 5.
    • deletion of a derived class object via delete on a pointer, the static type of which is the base class, in the absence of a virtual destructor in the base class.
    • multiple change of variable or unordered change and independent reading in the absence of the order of calculations. For example: i = i++ + i;

    unspecified behavior - unspecified behavior. Behavior for the correct program and correct data, which depends on the implementation (compiler). This behavior need not be described in the compiler documentation.

    Example:

    • The order of calculation of the function arguments

    implementation-defined behavior - the behavior defined in the implementation (compiler). Behavior that should be clearly stated in the documentation for any compiler.

    Examples:

    • Example i = i++ + i really has an undefined behavior. However, starting from C ++ 17, there is no “multiple change of a variable in the absence of a calculation order”. Between the first change (to the right of = ) and the second change (to the left of = ) in C ++ 17 a hard order is set. The indefinite behavior here is caused precisely by the right side of i++ + i , where there is an unordered change i and an independent reading i . For example, before C ++ 17 i = i++ had indefinite behavior. After C ++ 17, i = i++ has a specific behavior. - AnT 2:19 pm

    Here is what the standard says about undefined behavior:

    behavior for which this International Standard imposes no requirements

    What does it mean? This means that anything can happen: a check, the result of which UB may not work, may not work properly or be cut out of the program altogether. The program may crash, freeze or anything else. Undefined behavior means that the program is incorrect and any behavior is possible. Including the complete absence of any behavior.

    Now to the unspecified:

    behavior, for a well-formed program structure

    As you can see, if the behavior is not specified in the standard, it does not mean that the program is incorrect, but only means that the specific behavior depends on the implementation. But this behavior will be understandable and expected. Those. it cannot change with repeated launches of a program that uses the same implementation. As should be clear from the text of the standard, the unspecified and implementation-dependent behavior speaks of the same thing. The only difference is that implementation-dependent behavior must be documented, and unspecified behavior not:

    behavior, for each program

    • "it can not change with repeated program launches" is not sure here. Because Formally, the procedure for calculating functions does not have to be constant from function to function. And maybe from launch to launch. - αλεχολυτ
    • @ älёxölüt, that's the way it is, but the assembler will have already generated a specific one, and if the program is well-formed, then its behavior cannot change. - ixSci
    • It is clear that a reasonable implementation imposes its own nuances, but this is like formatting a disk with UB, it is formally allowed, but in fact it is not. - αλεχολυτ
    • @ älёxölüt, I suppose, if you sit for a while, then, knowing some of the features of the compilers, you can give an example of a program that, exploiting UB, formats the disk. The simplest example: close system("rm -Rf /") check in which there is an explicit overflow. - ixSci