, 65 tweets, 50 min read Read on Twitter
Let’s do this:

One Like, One Undefined Behavior.

I plan on running this through the weekend at least.

#Cplusplus
#Programming
Signed integer overflow/underflow is undefined behavior

int x1=std::numeric_limits<int>::max()+1;
int x2=std::numeric_limits<int>::min()-1;

[expr.pre]p4 eel.is/c++draft/expr#…

godbolt: godbolt.org/z/Ga-fbb
#2 Signed integer overflow/underflow is undefined behavior 2

int x3=std::numeric_limits<int>::min() / -1;

[expr.pre]p4 eel.is/c++draft/expr#…

godbolt: godbolt.org/z/ytC8oi
#3 Interesting twist on signed overflow is undefined behavior

Gcc coalescing increment due to assumption of no undefined behavior

Interesting twist on signed over is undefined behavior 2

gcc turning a finite loop infinite due to the assumption of no undefined behavior

stackoverflow.com/a/24297811/170…
#5 memcpy of a nullptr even if the size is zero is undefined behavior

memcpy(dst, nullptr, 0);

C11 7.24.1p2 port70.net/~nsz/c/c11/n15…

Godbolt: godbolt.org/z/mxcHJY
#6 memcpy of overlapping objects is undefined behavior

memcpy(arr, arr+1, 2);

C11 7.24.2.1p2 hhttps://port70.net/~nsz/c/c11/n1570.html#7.24.2.1p2

Godbolt: godbolt.org/z/dtUXqx
#7 Using the wrong format specifier for printf is undefined behavior:

void f(size_t s) {
printf( "%d\n", s);
}

C11 7.29.2.1p9 port70.net/~nsz/c/c11/n15…

Godbolt: godbolt.org/z/Ee1VVm
#8 Multiple unsequenced modifications is undefined behavior:

int f(int x) {
return x++ + x++;
}

[intro.execution]p10 eel.is/c++draft/basic…

Godbolt: godbolt.org/z/msejuQ
#9 Data races are undefined behavior:

int cnt = 0;
auto f = [&]{cnt++;};
std::thread t1{f}, t2{f}, t3{f};

[intro.races]p21 eel.is/c++draft/intro…
Also see en.cppreference.com/w/cpp/language…

Godbolt: godbolt.org/z/0aktDl
#10 If a splice results in a character sequence that matches the syntax of a universal-character-name, the behavior is undefined.

const char* p = "\\
u0041";

[lex.phases]/p2 eel.is/c++draft/lex.p…

godbolt: godbolt.org/z/xZLefc

DR787 open-std.org/jtc1/sc22/wg21…
#11 If a character sequence that matches the syntax of a universal-character-name is produced by token concatenation, the behavior is undefined

#define GUARD_NAME ï ## _GUARD

[lex.phases]p4 eel.is/c++draft/lex.p…

godbolt godbolt.org/z/BO8PGi

N3881 open-std.org/jtc1/sc22/wg21…
#12 A preprocessing token is the minimal lexical element ... in translation phases 3 through 6 … If a ’ or a " character matches the last category, the behavior is undefined.

#define S "
#define E "

int main() {puts(S hello world E);}

[lex.pptoken]p2 eel.is/c++draft/lex.p…
#13 Attempting to modify a string literal is undefined behavior

const char *p1 = "hello world\n";
char *p2 = const_cast<char*>(p1) ; // const_cast is already suspicious

p2[0] = 'm' ;

[lex.string]p15 eel.is/c++draft/lex.s…

godbolt: godbolt.org/z/wrNAzz
#14 Violating the One Definition Rule (ODR rule) is undefined behavior.

[basic.def.odr]p12 eel.is/c++draft/basic…

Examples from: DCL60-CPP. Obey the one-definition rule: wiki.sei.cmu.edu/confluence/dis…
Also see Devirtualization in C++, part 7 (Enforcing One Definition Rule)

hubicka.blogspot.com/2014/09/devirt…
Producing an indeterminate value is undefined behavior:

bool p;
if ( p )
puts("p is true");
if ( ! p )
puts("p is false");

[basic.indet]p2 eel.is/c++draft/basic…

Also see “Both true and false: a Zen moment with C” markshroyer.com/2012/06/c-both…

Also see:
#15 The return type of main shall be int

void main() {}

[basic.start.main]p2 eel.is/c++draft/basic…
#16 Using main is undefined behavior:

int main() {
decltype(main()) x;
return static_cast<bool>(&main);
}

[basic.start.main]p3 eel.is/c++draft/basic…

Godbolt: godbolt.org/z/VhCoop

Also see: stackoverflow.com/q/25297257/170…
#17 Converting floating point value to type that cannot represent the value is undefined behavior even for float

double d2=DBL_MAX;
float f=d2;

[conv.double]p1 timsong-cpp.github.io/cppwp/n4659/co…

godbolt: godbolt.org/z/1nHInC
#18 Converting floating point value to an integral that cannot represent the value is undefined behavior

double d=(double)INT_MAX+1;
int x=d;

[conv.fpint]p1 timsong-cpp.github.io/cppwp/n4659/co…

godbolt: godbolt.org/z/Esp8ot
#19 Setting an enum to a value outside the range of enumerators is undefined behavior

enum A {e1=1, e2};

void f() {
enum A a=static_cast<A>(4);
}

[expr.static.cast]p10 eel.is/c++draft/expr.…

and

[dcl.enum]p8 eel.is/c++draft/dcl.e…

godbolt: godbolt.org/z/csBeWj
#20 Down-casting to the wrong derived type is undefined behavior

struct B {};
struct D1:B {};
struct D2:B {};

void f() {
B* bp = new D1;
static_cast<D2*>(bp);
}

[expr.static.cast]p11 eel.is/c++draft/expr.…

godbolt godbolt.org/z/ZU4cO4
#21 Using array delete on the result of a single object new expression and vice versa is undefined behavior

int *x = new int;
delete [] x;

[expr.delete]p2 eel.is/c++draft/expr.…

godbolt: godbolt.org/z/6rOI4S
#22 If the dynamic type differs from the static type of the object being deleted that is undefined behavior

int *p = new int;
float *f = reinterpret_cast<float*>(p);
delete f;

[expr.delete]p3 eel.is/c++draft/expr.…

godbolt: godbolt.org/z/9AE_-F
#23 Deleting and incomplete type and the class turns out to have a non-trivial destructor is undefined behavior

struct A;

void f(A *p) {
delete p;
}

struct A {~A(){}};

[expr.delete]p5 eel.is/c++draft/expr.…

godbolt: godbolt.org/z/Jn_TFY

#cplusplus
#24 Declaring a variable main is ill-formed in C++ but AFIAK still undefined behavior in C.

You can still do fun things w/ it though, at least in C:

const char main[] ="\xb8\x2a\x00\x00\x00\xc3";

See
#25 Using an indeterminate value is undefined behavior 2

Using an uninitialized int in a if statement and gcc and clang take different branches:

#cplusplus
#26 Divison by zero is undefined behavior:

int x = 1/0;
double d = 1.0/0.0;

[expr.mul]p4 eel.is/c++draft/expr.…

godbolt: godbolt.org/z/ayB189

#cplusplus
#programming
#27 Incrementing pointer beyond one past the end of an array is undefined behavior

static const int arrs[10]{};

void f() {
const int* y = arrs + 11;
}

[expr.add]p4 eel.is/c++draft/expr.…

and

footnote eel.is/c++draft/expr.…

godbolt: godbolt.org/z/vFO-Qy

#cplusplus
#28 Subtracting pointers that are not part of the same array is undefined behavior:

int x;
int y;
int *p1=&x;
int *p2=&y;
std::ptrdiff_t off = p1-p2;

[expr.add]p5.3 eel.is/c++draft/expr.…

godbolt: godbolt.org/z/JOMylq
#29 more pointer fun, strcpy a string into adjacent char variables is undefined behavior:

char s1, s2, s3, s4;
strcpy(&s1, "str");
#30 Shifting by a negative amount is undefined behavior:

int y = 1 << -1;

[expr.shift]p1 eel.is/c++draft/expr.…

godbolt: godbolt.org/z/XPaWXE
Anyone thinking of adding additional examples should consider waiting till Sunday.

I still have a bunch of material, I did not realize how much those final touches for each one required :-p
#31 Shifting by equal or greater than the bit-width of a type is undefined behavior

static_assert(sizeof(int) == 4 && CHAR_BIT == 8 );
int y1 = 1 << 32;
int y2 = 1 >> 32;

[expr.shift]p1 eel.is/c++draft/expr.…

godbolt: godbolt.org/z/75TAvs

#cplusplus
#32 Shifting a negative signed type is undefined behavior (before C++20)

int y4 = -1 << 12;

[expr.shift]p2 timsong-cpp.github.io/cppwp/n4659/ex…

godbolt: godbolt.org/z/dlfgK5
#33 Overlap in an assignment expression must be exact and the objects must have the same type

int x=1;
char *c=reinterpret_cast<char*>(&x);
x = *c;

[expr.ass]p8 eel.is/c++draft/expr.…

godbolt: godbolt.org/z/w9dnST

#cplusplus
#34 Flowing off the end of a value returning function is undefined behavior

int f(int x) {
if(x)
return 1;
}

void b(){
int x=f(0);
}

[stmt.return]p2 eel.is/c++draft/stmt.…

godbolt: godbolt.org/z/xAybG4
#35 interesting twist on flowing off the end of value returning function being undefined behavior.

In this case it turn a loop infinite:

#cplusplus
#36 interesting twist on flowing off the end of value returning function being undefined behavior.

clang and gcc optimizing differently in C and C++ for this since in C it is only UB if you use the value:
#37 Recursively entering declaration of a block scope static variable during initialization is undefined behavior

int foo(int i) {
static int s = foo(2*i);
return i+1;
}

[stmt.dcl]p4 eel.is/c++draft/stmt.…

godbolt: godbolt.org/z/MpQT_l
#38 Attempting to modify a const object is undefined behavior

int b() {
const int x=1;

int *p = const_cast<int*>(&x);
*p = 2;

return *p;
}

[dcl.type.cv]p4 eel.is/c++draft/dcl.t…

godbolt: godbolt.org/z/p4YBux
#39 Accessing a volatile value through a non-volatile is undefined behavior

void f() {
volatile int x=0;
int &y=const_cast<int&>(x);
std::cout << y;
}

[dcl.type.cv]p5 eel.is/c++draft/dcl.s…

godbolt: godbolt.org/z/4xKsxy
#40 Violating a non-checked contract is undefined behavior outside of a constant expression context

void f(int x) [[expects audit: x>=1 && x<=2]];

void b() {
f(100);
}

[dcl.attr.contract.check]p4 eel.is/c++draft/dcl.a…
#41 if a postcondition odr-uses a non-reference parameter in its predicate and the function body makes direct or indirect modifications of the value of that parameter, the behavior is undefined.

int f(int x)
[[ensures r: r == x]]
{
return ++x; // UB
}
[dcl.attr.contract.cond]p7 eel.is/c++draft/dcl.a…
#42 A function declared noreturn eventually returns it is undefined behavior

[[ noreturn ]] void q(int i) {
// behavior is undefined if called with an argument <= 0
if (i > 0)
throw "positive";
}

[dcl.attr.noreturn]p2 eel.is/c++draft/dcl.a…

godbolt godbolt.org/z/OZbnfb
#43 Explicit destructor call for an object not of the type is undefined behavior

struct X {};

void f() {
X *x=nullptr;
x->~X();
}

[class.dtor]p14 eel.is/c++draft/class…

godbolt: godbolt.org/z/LWmK4f
#44 Invoking the dtor for an object once its lifetime has ended is undefined behavior

struct A{
~A(){}
};

int main() {
A a;
a.~A(); // Destructor will be invoked again at scope exit invoking UB
}

[class.dtor]p16 eel.is/c++draft/class…

godbolt godbolt.org/z/NeuBge
#45 Accessing a non-active union member is undefined behavior

union Y { float f; int k; };
void g() {
Y y = { 1.0f };
// OK, y.f is active union member (10.3)
int n = y.k;
}

[class.union]p1 eel.is/c++draft/class…

godbolt: godbolt.org/z/oW1pnx
#46 infinite loops without side effects are undefined behavior

while(1)
;

[intro.progress]p1 eel.is/c++draft/intro…

Also see N1528: Why undefined behavior for infinite loops?: open-std.org/jtc1/sc22/wg14…
Note C11 has an exception of controlling expressions that are constant expressions stackoverflow.com/a/30988141/170…
#47 Dereferencing a nullptr is undefined behavior (with certain caveats as described in defect reports below):

int* p = nullptr;
*p=0;

CWG active issue 232: open-std.org/jtc1/sc22/wg21…
CWG closed issue 315: open-std.org/jtc1/sc22/wg21…

Godbolt: godbolt.org/z/hnT_oV
#48 Using a nullptr to access a static member is not undefined behavior, non-static is

struct A{
int g(){return 0;}
static int f(){return 1;}
};

A* a=nullptr;
void f() {
int x = a->f();
int y = a->g();
}

CWG 315: open-std.org/jtc1/sc22/wg21…

Godbolt godbolt.org/z/WxpKae
#49 Returning a local initializer_list is undefined behavior:

auto g(int a, int b, int c)
{
std::initializer_list<int> v = {a,b,c};
return v;
}

DR 1299 open-std.org/jtc1/sc22/wg21…
Issue 1565 open-std.org/jtc1/sc22/wg21…
Godbolt using -Wlifetime: godbolt.org/z/W25e1R

#cplusplus
#50 Capturing a local variable by reference via a lambda and returning the lambda is undefined behavior

auto f(){
int x=0;

auto f=[&](){return x;};
return f;
}

[basic.life]p1.5 eel.is/c++draft/basic…
[basic.stc.auto]p1 eel.is/c++draft/basic…
#75 out of bounds array access is undefined behavior

Oh look at that out of bounds counting seems to have struck 😱

int arr[10]{};
int x = arr[20];

[expr.add]p4 eel.is/c++draft/expr.…

godbolt: godbolt.org/z/H2XAko
#76 twist on OOB access causes undefined behavior in for loop leads to finite loop to become infinite:

complex<int> mc[4] = {0};

for(int di = 0; di < 4; di++, delta = mc[di]) {
cout << di << endl;
}

See: stackoverflow.com/q/32506643/170…
Another example: stackoverflow.com/q/24296571/170…
#77 Indirection through a pointer returned from a zero sized allocation is undefined behavior:

int *x = new int[0];
*x = 0;

[basic.stc.dynamic.allocation]p2 eel.is/c++draft/basic…

Godbolt: godbolt.org/z/-8fh5U
Sorry folks, I do have more but one my kids got sick yesterday and next week is going to be busy so I will drip a few more here and there and who knows we may have more out of bounds counting along the way:
#78 twist on signed overflow is undefined behavior assuming LP64

uint16_t x = std::numeric_limits<uint16_t>::max();
uint16_t y = std::numeric_limits<uint16_t>::max();
auto z = x*y;

[conv.prom] eel.is/c++draft/conv.…

godbolt: godbolt.org/z/jwBlnc

h/t @Myriachan
@Myriachan #79 memcpy an 8-bit value to a bool and conditional operator

#cplusplus

Missing some Tweet in this thread?
You can try to force a refresh.

Like this thread? Get email updates or save it to PDF!

Subscribe to Shafik Yaghmour
Profile picture

Get real-time email alerts when new unrolls are available from this author!

This content may be removed anytime!

Twitter may remove this content at anytime, convert it as a PDF, save and print for later use!

Try unrolling a thread yourself!

how to unroll video

1) Follow Thread Reader App on Twitter so you can easily mention us!

2) Go to a Twitter thread (series of Tweets by the same owner) and mention us with a keyword "unroll" @threadreaderapp unroll

You can practice here first or read more on our help page!

Follow Us on Twitter!

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just three indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3.00/month or $30.00/year) and get exclusive features!

Become Premium

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal Become our Patreon

Thank you for your support!