Unreachable code facts for kids
In computer programming, unreachable code is part of the source code of a program which can never be executed because there exists no control flow path to the code from the rest of the program.
Unreachable code is sometimes also called dead code, although dead code may also refer to code that is executed but has no effect on the output of a program.
Unreachable code is generally considered undesirable for several reasons:
- It uses memory unnecessarily
- It can cause unnecessary use of the CPU's instruction cache
- This can also decrease data locality
- Time and effort may be spent testing, maintaining and documenting code which is never used
- Sometimes an automated test is the only thing using the code.
However, unreachable code can have some legitimate uses, like providing a library of functions for calling or jumping to manually via a debugger while the program is halted after a breakpoint. This is particularly useful for examining and pretty-printing the internal state of the program. It may make sense to have such code in the shipped product, so that a developer can attach a debugger to a client's running instance.
Contents
Causes
Unreachable code can exist for many reasons, such as:
- programming errors in complex conditional branches
- a consequence of the internal transformations performed by an optimizing compiler;
- incomplete testing of new or modified code
- Legacy code
- Code superseded by another implementation
- Unreachable code that a programmer decided not to delete because it is mingled with reachable code
- Potentially reachable code that current use cases never need
- Dormant code that is kept intentionally in case it is needed later
- Code used only for debugging.
Legacy code is that which was once useful but is no longer used or required. But unreachable code may also be part of a complex library, module or routine where it is useful to others or under conditions which are not met in a particular scenario.
An example of such a conditionally unreachable code may be the implementation of a general string formatting function in a compiler's runtime library, which contains complex code to process all possible arguments, of which only a small subset is actually used. Compilers will typically not be able to remove the unused code sections at compile time, as the behavior is largely determined by the values of arguments at run time.
Examples
In this fragment of C code:
int foo (int X, int Y)
{
return X + Y;
int Z = X * Y;
}
the definition int Z = X * Y; is never reached as the function always returns before it. Therefore, the Z need be neither allocated storage nor initialized.
goto fail bug
Apple's SSL/TLS from February 2014 contained a major security flaw known formally as CVE-2014-1266 and informally as the "goto fail bug". The relevant code fragment is:
static OSStatus
SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams,
uint8_t *signature, UInt16 signatureLen)
{
OSStatus err;
...
if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
goto fail;
goto fail;
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
goto fail;
...
fail:
SSLFreeBuffer(&signedHashes);
SSLFreeBuffer(&hashCtx);
return err;
}
Here, there are two successive goto fail
statements. In the syntax of the C language, the second is unconditional, and hence always skips the call to SSLHashSHA1.final
. As a consequence, err
will hold the status of the SHA1 update operation, and signature verification will never fail.
Here, the unreachable code is the call to the final
function. Applying the Clang compiler with the option -Weverything
includes unreachable code analysis, which would trigger an alarm for this code.
C++
In C++, some constructs are specified to have undefined behavior. A compiler is free to implement any behavior or none, and typically an optimizing compiler will assume the code is unreachable.
See also
In Spanish: Código inalcanzable para niños
- Code coverage
- Redundant code
- Dead code
- Oxbow code
- Halting problem – the general problem of determining whether a piece of code is unreachable is at least as hard as the halting problem and hence undecidable