8
\$\begingroup\$

What's the shortest, well-formed C++ code that exhibits undefined behavior?

\$\endgroup\$
5
  • 1
    \$\begingroup\$ What do you mean "runnable"? If it has UB, there's no guarantee it can be run. \$\endgroup\$ Aug 22, 2012 at 14:59
  • \$\begingroup\$ @R.MartinhoFernandes well, I mean that it starts. \$\endgroup\$ Aug 22, 2012 at 15:00
  • \$\begingroup\$ @LuchianGrigore that is very dependent on the compiler (version). \$\endgroup\$
    – rubenvb
    Aug 22, 2012 at 15:04
  • 1
    \$\begingroup\$ Define "exhibits". Does it need to show something? Or is it enough that the internal memory state is undefined at some point during the program? \$\endgroup\$
    – Mr Lister
    Aug 22, 2012 at 17:28
  • \$\begingroup\$ defined "well-formed". \$\endgroup\$ Aug 9, 2020 at 17:53

6 Answers 6

12
\$\begingroup\$
int main(){main;}

3.6.1 Main function [basic.start.main]

3 - [...] The function main shall not be used within a program.

Edit: this is diagnosable, so not UB.


int main(){for(;;);}

1.10 Multi-threaded executions and data races [intro.multithread]

24 - The implementation may assume that any thread will eventually do one of the following: — terminate, — make a call to a library I/O function, — access or modify a volatile object, or — perform a synchronization operation or an atomic operation.


int main(){int i=i;}

4.1 Lvalue-to-rvalue conversion [conv.lval]

1 - [...] If the object to which the glvalue refers is [...] uninitialized, a program that necessitates this conversion has undefined behavior.


//^L.

Here ^L is the form feed character, which is part of the basic character set. 4 characters (a newline is not required per 2.2:2). Undefined behaviour is per

2.8 Comments [lex.comment]

1 - If there is a form-feed or a vertical-tab character in [a //-style] comment, only white-space characters shall appear between it and the new-line that terminates the comment; no diagnostic is required.

\$\endgroup\$
9
  • \$\begingroup\$ the second one's not undefined. It can optimize out the for loop without issue. That is not undefined behavior. \$\endgroup\$
    – rubenvb
    Aug 22, 2012 at 15:19
  • 3
    \$\begingroup\$ @rubenvb stackoverflow.com/questions/3592557/… - anytime the standard says "the compiler may assume P," it is implied that a program which has the property not-P has undefined semantics. \$\endgroup\$
    – ecatmur
    Aug 22, 2012 at 15:28
  • \$\begingroup\$ yet the compiler may also assume no side effects when eliding copy constructors. \$\endgroup\$
    – rubenvb
    Aug 22, 2012 at 15:33
  • \$\begingroup\$ @rubenvb because that particular case is explicitly mentioned. \$\endgroup\$ Aug 22, 2012 at 15:36
  • 1
    \$\begingroup\$ @BogdanAlexandru your embedded project has undefined behaviour. That means that it might work as you expect now, but when you upgrade your compiler it will behave differently. \$\endgroup\$
    – ecatmur
    Oct 12, 2012 at 8:17
5
\$\begingroup\$
\u\
0000

This has eight characters, and has undefined behaviour, according to §2.2/1.

Each instance of a backslash character (\) immediately followed by a new-line character is deleted, splicing physical source lines to form logical source lines. Only the last backslash on any physical source line shall be eligible for being part of such a splice. If, as a result, a character sequence that matches the syntax of a universal-character-name is produced, the behavior is undefined.

\$\endgroup\$
5
  • \$\begingroup\$ this isn't & "program". A program has a main. \$\endgroup\$
    – rubenvb
    Aug 22, 2012 at 15:18
  • \$\begingroup\$ @rubenvb Try it on Hell++. It has undefined behaviour, so can be a program without a main. It's hard to enforce rules when you ask for a program that doesn't have any rules to follow (that's what UB means!). \$\endgroup\$ Aug 22, 2012 at 15:19
  • 3
    \$\begingroup\$ Based on the wording of the question, I think this qualifies -- it asks only for the shortest "code" that displays UB. Based on the "runnable" in the comment, I think the intent, however, was the shortest program, which would rule out your code, because according to §3.6.1/1: "A program shall contain a global function called main, which is the designated start of the program." As such, without main, what you have is ill-formed. \$\endgroup\$ Aug 22, 2012 at 16:13
  • 1
    \$\begingroup\$ @JerryCoffin He is using a freestanding environment where main is not required. You conveniently left out the rest of §3.6.1/1 which says "It is implementation-defined whether a program in a freestanding environment is required to define a main function.". This is a valid program ("valid" as in it's a "program" according to your argument). \$\endgroup\$
    – David
    Jan 9, 2015 at 10:04
  • \$\begingroup\$ Dang, just came here to bring that one. +1 \$\endgroup\$
    – Columbo
    Apr 24, 2015 at 22:27
2
\$\begingroup\$
#include. /*Imagine a new-line right after the dot*/

§16.2/4:

A preprocessing directive of the form

             #include  pp-tokens   new-line

(that does not match one of the two previous forms) is permitted. [..] If the directive resulting after all replacements does not match one of the two previous forms, the behavior is undefined.

\$\endgroup\$
2
  • \$\begingroup\$ Won't it parse the same if you remove the space before the dot? \$\endgroup\$
    – feersum
    Jun 5, 2015 at 21:27
  • \$\begingroup\$ @feersum Yep. That doesn't alter the idea, which is why I avoided it to enhance readability, but I guess it serves the point of the question to illustrate that the space can be omitted. Thanks! \$\endgroup\$
    – Columbo
    Jun 5, 2015 at 21:54
2
\$\begingroup\$
int main(){int i=1>>-1;}

Explanation:

C++98 and C++11 §5.8/1 both state that

The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand.

\$\endgroup\$
1
  • 3
    \$\begingroup\$ on a 32-bit system, isnt the length in bits of int typically 32? changing the RHS of the shift to -1 is the same number of chars and won't depend on integer sizes \$\endgroup\$
    – ardnew
    Aug 22, 2012 at 19:42
1
\$\begingroup\$

If one is to believe wikipedia, here's a few:

Modifying strings is said to cause undefined behavior. It's always worked for me.

int main(int c,char*v){v[0]='.';}

A non-void function with no return causes undefined return values.

int a(){}
int main(){return a();}

Division (of int?) by zero is supposedly undefined. All I know is that it crashes.

int main(int c){c/0;}
\$\endgroup\$
4
  • \$\begingroup\$ These are not legal code snippets. Main must be defined as int main(){} at the very least. \$\endgroup\$
    – rubenvb
    Aug 22, 2012 at 15:14
  • \$\begingroup\$ Damn, I was sure the question was about C. Sorry about that. \$\endgroup\$
    – shiona
    Aug 22, 2012 at 18:13
  • 1
    \$\begingroup\$ @shiona the second parameter should be char ** not char *. You're merely modifying part of a pointer value. In fact, argv is guaranteed to be safely modifiable. \$\endgroup\$
    – obataku
    Sep 9, 2012 at 15:12
  • \$\begingroup\$ The standard allows string literals to be read-only, so many implementations do that. It's correct for char *argv[] to not have any const qualifiers. You could crash by writing into a string literal with int main(){char *v="";*v=1;} \$\endgroup\$ May 15, 2016 at 3:53
-1
\$\begingroup\$
int main() { int* a; return a[0]; }
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.