Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Undefined behavior
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
== Overview == Some programming languages allow a program to operate differently or even have a different control flow from the source code, as long as it exhibits the same user-visible [[side effect (computer science)|side effects]], ''if undefined behavior never happens during program execution''. Undefined behavior is the name of a list of conditions that the program must not meet. In the early versions of [[C (programming language)|C]], undefined behavior's primary advantage was the production of performant [[compiler]]s for a wide variety of machines: a specific construct could be mapped to a machine-specific feature, and the compiler did not have to generate additional code for the runtime to adapt the side effects to match semantics imposed by the language. The program source code was written with prior knowledge of the specific compiler and of the [[computing platform|platforms]] that it would support. However, progressive standardization of the platforms has made this less of an advantage, especially in newer versions of C. Now, the cases for undefined behavior typically represent unambiguous [[software bug|bugs]] in the code, for example [[array index|indexing an array]] outside of its bounds. By definition, the [[runtime system|runtime]] can assume that undefined behavior never happens; therefore, some invalid conditions do not need to be checked against. For a [[compiler]], this also means that various [[program transformation]]s become valid, or their proofs of correctness are simplified; this allows for various kinds of optimizations whose correctness depend on the assumption that the program state never meets any such condition. The compiler can also remove explicit checks that may have been in the source code, without notifying the programmer; for example, detecting undefined behavior by testing whether it happened is not guaranteed to work, by definition. This makes it hard or impossible to program a portable fail-safe option (non-portable solutions are possible for some constructs). Current compiler development usually evaluates and compares compiler performance with benchmarks designed around micro-optimizations, even on platforms that are mostly used on the general-purpose desktop and laptop market (such as amd64). Therefore, undefined behavior provides ample room for compiler performance improvement, as the source code for a specific source code statement is allowed to be mapped to anything at runtime. For C and C++, the compiler is allowed to give a compile-time diagnostic in these cases, but is not required to: the implementation will be considered correct whatever it does in such cases, analogous to [[don't-care term]]s in digital logic. It is the responsibility of the programmer to write code that never invokes undefined behavior, although compiler implementations are allowed to issue diagnostics when this happens. Compilers nowadays have flags that enable such diagnostics, for example, <code>-fsanitize=undefined</code> enables the "undefined behavior sanitizer" ([[UBSan]]) in [[GNU Compiler Collection|gcc]] 4.9<ref>[https://developers.redhat.com/blog/2014/10/16/gcc-undefined-behavior-sanitizer-ubsan/ ''GCC Undefined Behavior Sanitizer β ubsan'']</ref> and in [[clang]]. However, this flag is not the default and enabling it is a choice of the person who builds the code. Under some circumstances there can be specific restrictions on undefined behavior. For example, the [[instruction set]] specifications of a [[central processing unit|CPU]] might leave the behavior of some forms of an instruction undefined, but if the CPU supports [[memory protection]] then the specification will probably include a blanket rule stating that no user-accessible instruction may cause a hole in the [[operating system]]'s security; so an actual CPU would be permitted to corrupt user registers in response to such an instruction, but would not be allowed to, for example, switch into [[supervisor mode]]. The runtime [[computing platform|platform]] can also provide some restrictions or guarantees on undefined behavior, if the [[toolchain]] or the [[runtime system|runtime]] explicitly document that specific constructs found in the [[source code]] are mapped to specific well-defined mechanisms available at runtime. For example, an [[interpreter (computing)|interpreter]] may document a particular behavior for some operations that are undefined in the language specification, while other interpreters or compilers for the same language may not. A [[compiler]] produces [[executable code]] for a specific [[application binary interface|ABI]], filling the [[semantic gap]] in ways that depend on the compiler version: the documentation for that compiler version and the ABI specification can provide restrictions on undefined behavior. Relying on these implementation details makes the software non-[[portable application|portable]], but portability may not be a concern if the software is not supposed to be used outside of a specific runtime. Undefined behavior can result in a program crash or even in failures that are harder to detect and make the program look like it is working normally, such as silent loss of data and production of incorrect results.
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)