├── README.md ├── all_section.md ├── basic_def_odr.md ├── basic_indet.md ├── basic_life.md ├── basic_start.md ├── lex_phases.md ├── lex_pptoken.md └── lex_string.md /README.md: -------------------------------------------------------------------------------- 1 | # cpp_undefined_behavior_enumerated 2 | Enumerating all of the Undefined Behavior in C++ 3 | 4 | - [All In One Page](https://github.com/shafik/cpp_undefined_behavior_enumerated/blob/master/all_section.md) 5 | 6 | - [basic.start](https://github.com/shafik/cpp_undefined_behavior_enumerated/blob/master/basic_start.md) 7 | - [lex.phases](https://github.com/shafik/cpp_undefined_behavior_enumerated/blob/master/lex_phases.md) 8 | - [lex.pptoken](https://github.com/shafik/cpp_undefined_behavior_enumerated/blob/master/lex_pptoken.md) 9 | - [lex.string](https://github.com/shafik/cpp_undefined_behavior_enumerated/blob/master/lex_string.md) 10 | - [basic.def.odr](https://github.com/shafik/cpp_undefined_behavior_enumerated/blob/master/basic_def_odr.md) 11 | - [basic.life](https://github.com/shafik/cpp_undefined_behavior_enumerated/blob/master/basic_life.md) 12 | - [basic.indet](https://github.com/shafik/cpp_undefined_behavior_enumerated/blob/master/basic_indet.md) 13 | -------------------------------------------------------------------------------- /all_section.md: -------------------------------------------------------------------------------- 1 | # [lex] 2 | ## [lex.phases] 3 | - if a splice results in a character sequence that matches the syntax of a universal-character-name, the behavior is undefined. 4 | - [\[lex.phases\]p1.2](http://eel.is/c++draft/lex.phases#1.2) 5 | - Example from [Stack Overflow question](https://stackoverflow.com/q/43824729/1708801): 6 | ```cpp 7 | const char* p = "\\ 8 | u0041"; 9 | ``` 10 | - [Examples live](https://godbolt.org/z/xZLefc) 11 | - Rationale 12 | - [DR 787](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#787) 13 | - [N3881 “Fixing the specification of universal-character-names”](http://open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3881.pdf) 14 | 15 | - If a character sequence that matches the syntax of a universal-character-name is produced by token concatenation (19.3.3), the behavior is undefined. *\[lex.phases\]/p4* 16 | - [\[lex.phases\]p1.4](http://eel.is/c++draft/lex.phases#1.4) 17 | - Examples: 18 | ```cpp 19 | #define GUARD_NAME ï ## _GUARD // UB per current spec 20 | #define COLUMN "ï" ## _column // UB per current spec 21 | ``` 22 | - [Examples live](https://godbolt.org/z/BO8PGi) 23 | - Rationale 24 | - [DR 787](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#787) 25 | - [N3881 “Fixing the specification of universal-character-names”](http://open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3881.pdf) 26 | 27 | ## [lex.pptoken] 28 | - A preprocessing token is the minimal lexical element of the language in translation phases 3 through 6. … If a **’** or a **"** character matches the last category, the behavior is undefined. *\[lex.pptoken\]/p2* 29 | - Example [Why can't we use the preprocessor to create custom-delimeted strings?](https://stackoverflow.com/q/16798853/1708801) 30 | ```cpp 31 | #define STR_START " 32 | #define STR_END " 33 | 34 | int puts(const char *); 35 | 36 | int main() { 37 | puts(STR_START hello world STR_END); 38 | } 39 | ``` 40 | - [Examples live](https://godbolt.org/z/mqiAJw) 41 | - Discussion 42 | - [Should it be ill-formed](https://groups.google.com/a/isocpp.org/forum/#!msg/std-discussion/lk1qAvCiviY/Zer-8iL88rUJ) 43 | - Rationale 44 | - Preprocessing token are generated during phase 3 so string and character literals as well and header names are identified at this point. both ‘ and “ would only be valid as part of one of these tokens, any left over after this point perhaps as part of a macro would not be valid since they could not tokenized as needed anymore. Macros are expanded as part of phase 4. 45 | 46 | ## [lex.string] 47 | - The effect of attempting to modify a string literal is undefined 48 | - Examples: 49 | ```cpp 50 | const char *p1 = "hello world\n"; 51 | char *p2 = const_cast(p1) ; // const_cast is already suspicious 52 | 53 | p2[0] = 'm' ; 54 | ``` 55 | - [Examples live](https://godbolt.org/z/wrNAzz) 56 | - Rationale *\[lex.string\]p8 57 | > Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow 58 | string literal **has type “array of n const char”**, where n is the size of the string as defined below, and has 59 | static storage duration (6.6.4). 60 | 61 | # [basic] 62 | ## [basic.def.odr] 63 | - There can be more than one definition of a class type (Clause 12), enumeration type (10.2), inline function with external linkage (10.1.6), inline variable with external linkage (10.1.6), class template (Clause 17), non-static function template (17.6.6), concept (17.6.8), static data member of a class template (17.6.1.3), member function of a class template (17.6.1.1), or template specialization for which some template parameters are not specified (17.8, 17.6.5) in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements. Given such an entity named D defined in more than one translation unit, then ... If the definitions of D do not satisfy these requirements, then the behavior is undefined. 64 | - [\[basic.def.odr\]p12](http://eel.is/c++draft/basic.def.odr#12) 65 | - [Examples from: DCL60-CPP. Obey the one-definition rule](https://wiki.sei.cmu.edu/confluence/display/cplusplus/DCL60-CPP.+Obey+the+one-definition+rule) 66 | 67 | ```cpp 68 | // a.cpp 69 | struct S { 70 | int a; 71 | }; 72 | 73 | // b.cpp 74 | // S in b.cpp does not consist of the same sequence of token as S in a.cpp 75 | class S { 76 | public: 77 | int a; 78 | }; 79 | ``` 80 | 81 | 82 | ```cpp 83 | const int n = 42; 84 | 85 | int g(const int &lhs, const int &rhs); 86 | 87 | inline int f(int k) { 88 | return g(k, n); // f() has external linkage 89 | // n has internal linkage but is our-used by g() 90 | // n will not be identical in all transition units 91 | } 92 | ``` 93 | 94 | - Rationale: 95 | - [Devirtualization in C++, part 7 (Enforcing One Definition Rule) ](http://hubicka.blogspot.com/2014/09/devirtualization-in-c-part-6-enforcing.html) 96 | 97 | ## [basic.life] 98 | - A program may end the lifetime of any object by reusing the storage which the object occupies or by explicitly calling the 99 | destructor for an object of a class type with a non-trivial destructor. For an object of a class type with a non-trivial destructor, 100 | the program is not required to call the destructor explicitly before the storage which the object occupies is reused or released; 101 | however, **if there is no explicit call to the destructor or if a delete-expression ([expr.delete]) is not used to release the storage, 102 | the destructor shall not be implicitly called and any program that depends on the side effects produced by the destructor has undefined behavior.** 103 | - [\[basic.life\]p5](http://eel.is/c++draft/basic.life#5) 104 | - [Pull request 2342 indicates this may not be undefined behavior at all](https://github.com/cplusplus/draft/pull/2342) and seeks the following edit
105 | implicitly called and any program that depends on the side effects produced by the destructor has undefined behaviorimplicitly called. 106 | 107 | ## [basic.indet] 108 | - If an indeterminate value is produced by an evaluation, the behavior is undefined except in the following 109 | cases 110 | - [\[basic.indet\]p2](http://eel.is/c++draft/basic.indet#2) 111 | - Examples 112 | ```cpp 113 | int f(bool b) { 114 | unsigned char c; 115 | unsigned char d = c; // OK, d has an indeterminate value 116 | int e = d; // undefined behavior 117 | return b ? d : 0; // undefined behavior if b is true 118 | } 119 | ``` 120 | - Rationale 121 | - [WG14 Defect report 260](http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_260.htm) 122 | - [WG14 Defect report 451](http://www.open-std.org/Jtc1/sc22/WG14/www/docs/dr_451.htm) 123 | - Tl;DR; We have two case one in which using an indeterminate value is undefined behavior and this is because many type can have trap representations and using these value are undefined behavior. In the case of narrow character types the underlying values and type representation are one to one and therefore we don’t have a trap representation but they do retain their indeterminateness. 124 | 125 | ## [basic.start] 126 | 127 | - An implementation shall not predefine the main function. This function shall not be overloaded. Its type shall have C++ language linkage and it shall have a declared return type of type int, but otherwise its type is implementation-defined. 128 | - [\[basic.start.main\]p2](http://eel.is/c++draft/basic.start#main-2) 129 | - Examples: 130 | ```cpp 131 | void main() {} 132 | ``` 133 | - Tools 134 | - [Compiler static analysis, generates warnings or errors for void main](https://wandbox.org/permlink/9YlvHEA88lS0CbvV) 135 | 136 | - The function main shall not be used within a program 137 | - [\[basic.start.main\]p3](http://eel.is/c++draft/basic.start#main-3) 138 | - Examples: 139 | - [Is it illegal to take address of main() function?](https://stackoverflow.com/q/15525613/1708801) 140 | - [Why does gcc warn about decltype(main()) but not clang?](https://stackoverflow.com/q/25297257/1708801) 141 | 142 | ```cpp 143 | printf( “%p\n”, &main ) ; 144 | decltype(main()) x = 0; 145 | ``` 146 | 147 | ```cpp 148 | int main() { 149 | std::cout << reinterpret_cast(&main) ; 150 | } 151 | ``` 152 | 153 | - Tools 154 | - [Compiler static analysis via -pedantic flag gcc/clang for taking address of main](https://wandbox.org/permlink/atm7dJ1LXaVBkCsU) 155 | - [Compiler static analysis via -pedantic flag gcc/clang decltype main](https://wandbox.org/permlink/WvPFbU4hteDOX4w2) 156 | 157 | - Rationale: 158 | - From ARM section 3.4 Start and Termination 159 | > This is to ensure full freedom of the implementation of the interface between a C++ program and its environment. 160 | > One could imagine an implementation where main() was not implemented as a function. 161 | - [\[ub\] What does "The function main shall not be used within a program" mean?](http://www.open-std.org/pipermail/ub/2014-January/000474.html) 162 | 163 | # [expr] 164 | 165 | ## [expr.pre] 166 | - Signed integer overflow/underflow is undefined behavior 167 | - [\[expr.pre\]](http://eel.is/c++draft/expr#pre-4) 168 | - Examples 169 | ```cpp 170 | int x1=std::numeric_limits::max()+1; 171 | int x2=std::numeric_limits::min()-1; 172 | int x3=std::numeric_limits::min() / -1; 173 | ``` 174 | - [Examples live 1](https://godbolt.org/z/4M9uR7) and [examples live 2](https://godbolt.org/z/3ToiDL) 175 | 176 | ## [conv.double] 177 | 178 | - Converting floating point value to type that cannot represent the value is undefined behavior even for float 179 | - [\[conv.double\]p1](https://timsong-cpp.github.io/cppwp/n4659/conv.double#1) 180 | - Examples 181 | ```cpp 182 | double d2=DBL_MAX; 183 | float f=d2; 184 | ``` 185 | - [examples live](https://godbolt.org/z/p1y5JK) 186 | 187 | ## [conv.fpint] 188 | 189 | - Converting floating point value to an integral that cannot represent the value is undefined behavior 190 | - [\[conv.fpint\]p1]( https://timsong-cpp.github.io/cppwp/n4659/conv.fpint#1) 191 | - Examples 192 | ```cpp 193 | double d=(double)INT_MAX+1; 194 | int x=d; 195 | ``` 196 | - [Examples live](https://godbolt.org/z/8p0t_C) 197 | 198 | ## [expr.call] 199 | - Calling a function through an expression whose function type is different from the function type of the called 200 | function’s definition results in undefined behavior 201 | - [\[expr.call\]p6]( http://eel.is/c++draft/expr.call#6) 202 | - Examples 203 | ```cpp 204 | int f_c(int); 205 | 206 | using c1 = int(*)(int); 207 | using c2 = int(*)(int,int); 208 | 209 | int f(c2 func) { 210 | return func(1,2); 211 | } 212 | 213 | int main() { 214 | f(reinterpret_cast(f_c)); 215 | } 216 | ``` 217 | - [Examples live](https://gcc.godbolt.org/z/2gUEol) 218 | 219 | ## [expr.static.cast] 220 | - If the object of type “cv1 B” is actually a base class subobject of an object of type D, the result refers to the 221 | enclosing object of type D. Otherwise, the behavior is undefined. 222 | - [\[expr.static.cast\]](http://eel.is/c++draft/expr.static.cast#2) 223 | - Examples: 224 | ```cpp 225 | struct B {}; 226 | struct D1:B {}; 227 | struct D2:B {}; 228 | 229 | void f() { 230 | D1 d; 231 | B &b = d; 232 | static_cast(b); 233 | } 234 | ``` 235 | - [Examples live](https://godbolt.org/z/z7RTFJ) 236 | 237 | - Setting an enum to a value outside the range of enumerators is undefined behavior 238 | - [\[expr.static.cast\]p10](http://eel.is/c++draft/expr.static.cast#10) and [\[dcl.enum\]p8](http://eel.is/c++draft/dcl.enum#8) 239 | - Examples 240 | ```cpp 241 | enum A {e1=1, e2}; 242 | 243 | void f() { 244 | enum A a=static_cast(4); 245 | } 246 | ``` 247 | - [Examples live](https://wandbox.org/permlink/YWXO1IQt3DLSSHmb) 248 | 249 | - Down-casting to the wrong derived type is undefined behavior 250 | - [\[expr.static.cast\]p11](http://eel.is/c++draft/expr.static.cast#11) 251 | - Examples 252 | ```cpp 253 | struct B {}; 254 | struct D1:B {}; 255 | struct D2:B {}; 256 | 257 | void f() { 258 | B* bp = new D1; 259 | static_cast(bp); 260 | } 261 | ``` 262 | - [Examples lives](https://godbolt.org/z/gfT5Bw) 263 | 264 | ## [expr.delete] 265 | - Using array delete on the result of a single object new expression and vice versa is undefined behavior 266 | - [\[expr.delete\]p2])http://eel.is/c++draft/expr.delete#2) 267 | - Examples 268 | ```cpp 269 | int *x = new int; 270 | delete [] x; 271 | ``` 272 | - [Examples live](https://godbolt.org/z/KI8XSc) 273 | 274 | - If the dynamic type differs from the static type of the object being deleted that is undefined behavior 275 | - [\[expr.delete\]p3](http://eel.is/c++draft/expr.delete#3) 276 | - Examples 277 | ```cpp 278 | int *p = new int; 279 | float *f = reinterpret_cast(p); 280 | delete f; 281 | ``` 282 | - [Examples lives](https://godbolt.org/z/Pj_Ljb) 283 | 284 | - Deleting and incomplete type and the class turns out to have a non-trivial destructor is undefined behavior 285 | - [\[expr.delete\]p5](http://eel.is/c++draft/expr.delete#5) 286 | - Examples 287 | ```cpp 288 | struct A; 289 | 290 | void f(A *p) { 291 | delete p; 292 | } 293 | 294 | struct A {~A(){}}; 295 | ``` 296 | - [Examples live](https://godbolt.org/z/Jc6lKv) 297 | 298 | ## [expr.mptr.oper] 299 | - If the dynamic type of E1 does not contain the member to which E2 refers, the behavior is undefined 300 | - [\[expr.mptr.oper\]p4](http://eel.is/c++draft/expr.mptr.oper#4) 301 | - Examples: 302 | ```cpp 303 | struct B{}; 304 | struct D:B{int x;}; 305 | 306 | void f(){ 307 | B *b= new B; 308 | D *d=static_cast(b); 309 | int D::* p=&D::x; 310 | (*d).*p=1; 311 | } 312 | ``` 313 | - [Examples live](https://godbolt.org/z/wgNkKz) 314 | 315 | - If the second operand is the null member pointer value (7.3.12), the behavior is undefined. 316 | - [\[expr.mptr.oper\]p6](http://eel.is/c++draft/expr.mptr.oper#6) 317 | - Examples: 318 | ```cpp 319 | struct S { 320 | int i; 321 | }; 322 | 323 | void f() 324 | { 325 | S cs; 326 | int S::* pm = nullptr; 327 | cs.*pm = 88; 328 | } 329 | ``` 330 | - [Examples live](https://godbolt.org/) 331 | 332 | ## [expr.mul] 333 | - Divison by zero is undefined behavior 334 | - [\[expr.mul\]p4](http://eel.is/c++draft/expr.mul#4) 335 | - Examples: 336 | ```cpp 337 | int x = 1/0; 338 | double d = 1.0/0.0; 339 | ``` 340 | - [Examples live](https://godbolt.org/z/d42Fsi) 341 | 342 | ## [expr.add] 343 | - Incrementing pointer beyond one past the end of an array is undefined behavior 344 | - [\[expr.add\]p4](http://eel.is/c++draft/expr.add#4) and [footnote](http://eel.is/c++draft/expr.add#footnote-80) 345 | - Examples: 346 | ```cpp 347 | static const int arrs[10]{}; 348 | 349 | void f() { 350 | const int* y = arrs + 11; 351 | } 352 | ``` 353 | - [Examples live](https://godbolt.org/z/Oo9lWi) 354 | 355 | 356 | - Subtracting pointers that are not part of the same array is undefined behavior 357 | - [\[expr.add\]p5.3](http://eel.is/c++draft/expr.add#5.3) 358 | - Examples: 359 | ```cpp 360 | void f() { 361 | int x; 362 | int y; 363 | int *p1=&x; 364 | int *p2=&y; 365 | std::ptrdiff_t off = p1-p2; 366 | } 367 | ``` 368 | - [Examples live](https://godbolt.org/z/BxwQjE) 369 | 370 | ## [expr.shift] 371 | - Shifting by a negative amount is undefined behavior 372 | - [\[expr.shift\]p1](http://eel.is/c++draft/expr.shift#1) 373 | - Examples 374 | ```cpp 375 | int y = 1 << -1; 376 | ``` 377 | - [Examples live](https://godbolt.org/z/op_tEL) 378 | 379 | - Shifting by equal or greater than the bit-width of a type is undefined behavior 380 | - [\[expr.shift\]p1](http://eel.is/c++draft/expr.shift#1) 381 | - Examples: 382 | ```cpp 383 | int y1 = 1 << 32; 384 | int y2 = 1 >> 32; 385 | ``` 386 | - [Examples live](https://godbolt.org/z/fx156-) 387 | 388 | - Shifting a negative signed type is undefined behavior (before C++20) 389 | - [\[expr.shift\]p2](https://timsong-cpp.github.io/cppwp/n4659/expr.shift#2) 390 | - Examples: 391 | ```cpp 392 | int y4 = -1 << 12; 393 | ``` 394 | - [Examples live](https://godbolt.org/z/v3B1ij) 395 | 396 | 397 | ## [expr.ass] 398 | - Overlap in an assignment expression must be exact and the objects must have the same type 399 | - [\[expr.ass\]p8](http://eel.is/c++draft/expr.ass#8) 400 | - Examples: 401 | ```cpp 402 | int x=1; 403 | char *c=reinterpret_cast(&x); 404 | x = *c; 405 | ``` 406 | - [Examples live](https://godbolt.org/z/LGBL7k) 407 | 408 | # [stmt.stmt] 409 | ## [stmt.return] 410 | - Flowing off the end of a value returning function is undefined behavior 411 | - [\[stmt.return\]p2](http://eel.is/c++draft/stmt.return#2.sentence-8) 412 | - Examples: 413 | ```cpp 414 | int f(int x) { 415 | if(x) 416 | return 1; 417 | } 418 | 419 | void b(){ 420 | int x=f(0); 421 | } 422 | ``` 423 | - [Examples live](https://godbolt.org/z/62CGnB) 424 | - [Also see]( https://twitter.com/shafikyaghmour/status/975224687444688896) 425 | 426 | ## [stmt.dcl] 427 | - Recursively entering declaration of a block scope static variable during initialization is undefined behavior 428 | - [\[stmt.dcl\]p4](http://eel.is/c++draft/stmt.dcl#4) 429 | - Examples: 430 | ```cpp 431 | int foo(int i) { 432 | static int s = foo(2*i); 433 | return i+1; 434 | } 435 | ``` 436 | - [Examples live](https://godbolt.org/z/mT9a-_) 437 | 438 | # [dcl.dcl] 439 | ## [dcl.type.cv] 440 | - Attempting to modify a const object is undefined behavior 441 | - [\[dcl.type.cv\]p4](http://eel.is/c++draft/dcl.type.cv#4) 442 | - Examples: 443 | ```cpp 444 | int bar() { 445 | const int x=1; 446 | 447 | int *p = const_cast(&x); 448 | *p = 2; 449 | 450 | return *p; 451 | } 452 | ``` 453 | - [Examples live](https://godbolt.org/z/MArrbe) 454 | 455 | - Accessing a volatile value through a non-volatile is undefined behavior 456 | - [\[dcl.type.cv\]p5](http://eel.is/c++draft/dcl.spec#dcl.type.cv-5) 457 | - Examples: 458 | ```cpp 459 | void f() { 460 | volatile int x=0; 461 | int &y=const_cast(x); 462 | std::cout << y; 463 | } 464 | ``` 465 | -[Examples live](https://godbolt.org/z/4xKsxy) 466 | 467 | 468 | ## [dcl.attr.contract.syn] 469 | - In contracts side effects in a predicate to an object whose lifetime did not begin and end within the evaluation of the predicate are undefined behavior 470 | - [\[dcl.attr.contract.syn\]p6](http://eel.is/c++draft/dcl.attr.contract#syn-6) 471 | - Examples: 472 | ```cpp 473 | int min = -42; 474 | constexpr int g(int x) { 475 | /* ... */ 476 | [[assert: ++min > 0]]; // undefined behavior 477 | /* ... */ 478 | return 0; 479 | } 480 | ``` 481 | - [Examples live](http://fragata.arcos.inf.uc3m.es/#g:!((g:!((g:!((h:codeEditor,i:(j:1,lang:c%2B%2B,source:'int+min+%3D+-42%3B%0Aconstexpr+int+g(int+x)%7B%0A++/*+...+*/%0A++%5B%5Bassert:+%2B%2Bmin+%3E+0%5D%5D%3B+//+undefined+behavior%0A++/*+...+*/%0A++return+0%3B%0A%7D'),l:'5',n:'0',o:'C%2B%2B+source+%231',t:'0')),k:50,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((g:!((h:compiler,i:(compiler:clang%2B%2B-master,filters:(b:'0',binary:'1',commentOnly:'0',demangle:'0',directives:'0',execute:'1',intel:'0',trim:'0'),lang:c%2B%2B,libs:!(),options:'',source:1),l:'5',n:'0',o:'Clang+6.0.0+x86_64+%5Bclang-contracts%5D+(master)+(Editor+%231,+Compiler+%231)+C%2B%2B',t:'0')),k:50,l:'4',m:50,n:'0',o:'',s:0,t:'0'),(g:!((h:output,i:(compiler:1,editor:1),l:'5',n:'0',o:'%231+with+Clang+6.0.0+x86_64+%5Bclang-contracts%5D+(master)',t:'0')),header:(),l:'4',m:50,n:'0',o:'',s:0,t:'0')),k:50,l:'3',n:'0',o:'',t:'0')),l:'2',n:'0',o:'',t:'0')),version:4) 482 | 483 | ## [dcl.attr.contract.syn] 484 | - 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. 485 | - [\[dcl.attr.contract.cond\]p7](http://eel.is/c++draft/dcl.attr.contract#cond-7) 486 | - Examples: 487 | ```cpp 488 | int f(int x) 489 | [[ensures r: r == x]] 490 | { 491 | return ++x; // UB 492 | } 493 | ``` 494 | - [Examples live](http://fragata.arcos.inf.uc3m.es/#g:!((g:!((g:!((h:codeEditor,i:(j:1,lang:c%2B%2B,source:'int+f(int+x)%0A++%5B%5Bensures+r:+r+%3D%3D+x%5D%5D%0A%7B%0A++return+%2B%2Bx%3B+//+UB%0A%7D%0A'),l:'5',n:'0',o:'C%2B%2B+source+%231',t:'0')),k:50,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((g:!((h:compiler,i:(compiler:clang%2B%2B-master,filters:(b:'0',binary:'1',commentOnly:'0',demangle:'0',directives:'0',execute:'1',intel:'0',trim:'0'),lang:c%2B%2B,libs:!(),options:'',source:1),l:'5',n:'0',o:'Clang+6.0.0+x86_64+%5Bclang-contracts%5D+(master)+(Editor+%231,+Compiler+%231)+C%2B%2B',t:'0')),k:50,l:'4',m:50,n:'0',o:'',s:0,t:'0'),(g:!((h:output,i:(compiler:1,editor:1),l:'5',n:'0',o:'%231+with+Clang+6.0.0+x86_64+%5Bclang-contracts%5D+(master)',t:'0')),header:(),l:'4',m:50,n:'0',o:'',s:0,t:'0')),k:50,l:'3',n:'0',o:'',t:'0')),l:'2',n:'0',o:'',t:'0')),version:4) 495 | 496 | ## [dcl.attr.contract.check] 497 | - Violating a non-checked contract is undefined behavior outside of a constant expression context 498 | - [\[dcl.attr.contract.check\]p4](http://eel.is/c++draft/dcl.attr.contract#check-4) 499 | - Rationale see [p1321r0](http://open-std.org/JTC1/SC22/WG21/docs/papers/2018/p1321r0.html) and [p1490r0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1490r0.html) 500 | - Examples: 501 | ```cpp 502 | void f(int x) [[expects audit: x>=1 && x<=2]]; 503 | 504 | void b() { 505 | f(100); 506 | } 507 | ``` 508 | - [Examples live](http://fragata.arcos.inf.uc3m.es/#g:!((g:!((g:!((h:codeEditor,i:(j:1,lang:c%2B%2B,source:'void+f(int+x)+%5B%5Bexpects+audit:+x%3E%3D1+%26%26+x%3C%3D2%5D%5D%3B%0A%0Avoid+b()+%7B%0A++f(100)%3B%0A%7D'),l:'5',n:'0',o:'C%2B%2B+source+%231',t:'0')),k:50,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((g:!((h:compiler,i:(compiler:clang%2B%2B-master,filters:(b:'0',binary:'1',commentOnly:'0',demangle:'0',directives:'0',execute:'1',intel:'0',trim:'0'),lang:c%2B%2B,libs:!(),options:'',source:1),l:'5',n:'0',o:'Clang+6.0.0+x86_64+%5Bclang-contracts%5D+(master)+(Editor+%231,+Compiler+%231)+C%2B%2B',t:'0')),k:50,l:'4',m:50,n:'0',o:'',s:0,t:'0'),(g:!((h:output,i:(compiler:1,editor:1),l:'5',n:'0',o:'%231+with+Clang+6.0.0+x86_64+%5Bclang-contracts%5D+(master)',t:'0')),header:(),l:'4',m:50,n:'0',o:'',s:0,t:'0')),k:50,l:'3',n:'0',o:'',t:'0')),l:'2',n:'0',o:'',t:'0')),version:4) 509 | 510 | ## [dcl.attr.noreturn] 511 | - A function declared noreturn eventually returns it is undefined behavior 512 | - [\[dcl.attr.noreturn\]p2](http://eel.is/c++draft/dcl.attr.noreturn#2) 513 | - Examples: 514 | ```cpp 515 | [[ noreturn ]] void q(int i) { // behavior is undefined if called with an argument <= 0 516 | if (i > 0) 517 | throw "positive"; 518 | } 519 | ``` 520 | - [Examples live](https://godbolt.org/z/_8GQBg) 521 | 522 | # [class] 523 | 524 | ## [class.mfct.non-static] 525 | - Calling a non-static member function of a class with an object that is not of that type is undefined behavior 526 | - [\[class.mfct.non-static\]p2](http://eel.is/c++draft/class.mem#class.mfct.non-static-2) 527 | - Examples: 528 | ```cpp 529 | struct X { 530 | int x=1; 531 | int f() { return x;} 532 | }; 533 | 534 | struct A {int x=3;}; 535 | 536 | int f(X*x) { 537 | return x->f(); 538 | } 539 | ``` 540 | - [Examples live](https://godbolt.org/z/0zBLzy) 541 | 542 | ## [class.dtor] 543 | - Explicit destructor call for an object not of the type is undefined behavior 544 | - [\[class.dtor\]p14](http://eel.is/c++draft/class.dtor#14) 545 | - Examples: 546 | ```cpp 547 | struct X {}; 548 | 549 | void f() { 550 | X *x=nullptr; 551 | x->~X(); 552 | } 553 | ``` 554 | - [Examples live](https://godbolt.org/z/Qola5k) 555 | 556 | - Invoking the destructor for an object once its lifetime has ended is undefined behavior 557 | - [\[class.dtor\]p16](http://eel.is/c++draft/class.dtor#16) 558 | - Examples: 559 | ```cpp 560 | struct A{ 561 | ~A(){} 562 | }; 563 | 564 | int main() { 565 | A a; 566 | a.~A(); // Destructor will be invoked again at scope exit invoking UB 567 | } 568 | ``` 569 | - [Examples live](https://godbolt.org/z/kHMPig) 570 | 571 | ## [class.union] 572 | - Accessing a non-active union member is undefined behavior 573 | - [\[class.union\]p1](http://eel.is/c++draft/class.union#1) 574 | - Examples: 575 | ```cpp 576 | union Y { float f; int k; }; 577 | void g() { 578 | Y y = { 1.0f }; // OK, y.f is active union member (10.3) 579 | int n = y.k; 580 | } 581 | ``` 582 | - [Examples live](https://godbolt.org/z/LbbRnS) 583 | 584 | ## [class.abstract] 585 | - Calling a virtual function from a constructor or destructor in an abstract class is undefined behavior 586 | - [\[class.abstract\]p6](http://eel.is/c++draft/class.derived#class.abstract-6) 587 | - Examples: 588 | ```cpp 589 | struct B { 590 | virtual void f()=0; 591 | B() { f();} 592 | }; 593 | 594 | struct D : B{ 595 | void f() override { } 596 | }; 597 | ``` 598 | - [Examples live](https://godbolt.org/z/mFTX2B) 599 | 600 | ## [class.base.init] 601 | - Calling a member function before all baes are initialized is undefined behavior 602 | - [\[class.base.init\]p16](http://eel.is/c++draft/class.base.init#16) 603 | - Examples: 604 | ```cpp 605 | struct B { 606 | B(int); 607 | }; 608 | 609 | struct D : public B { 610 | int f(); 611 | D() : B(f()) {} 612 | }; 613 | ``` 614 | - [Examples live](https://godbolt.org/z/um0iNu) 615 | 616 | ## [class.cdtor] 617 | - For an object with a non-trivial constructor, referring to any non-static member or base class of the object 618 | before the constructor begins execution results in undefined behavior 619 | - [\[class.cdtor\]p1](http://eel.is/c++draft/class.cdtor#1) 620 | - Examples 621 | ```cpp 622 | struct W { int j; }; 623 | struct X : public virtual W { }; 624 | 625 | struct Y { 626 | int* p; 627 | X x; 628 | Y() : p(&x.j) { // undefined, x is not yet constructed 629 | } 630 | }; 631 | ``` 632 | - [Examples live](https://godbolt.org/z/fFbAY9) 633 | 634 | - To explicitly or implicitly convert a pointer (a glvalue) referring to an object of class X to a pointer (reference) 635 | to a direct or indirect base class B of X, the construction of X and the construction of all of its direct or 636 | indirect bases that directly or indirectly derive from B shall have started and the destruction of these classes 637 | shall not have completed, otherwise the conversion results in undefined behavior 638 | - [\[class.cdtor\]p3](http://eel.is/c++draft/class.cdtor#3) 639 | - Examples: 640 | ```cpp 641 | struct A { }; 642 | struct B : virtual A { }; 643 | struct C : B { }; 644 | struct D : virtual A { D(A*); }; 645 | struct X { X(A*); }; 646 | 647 | struct E : C, D, X { 648 | E() : D(this), // undefined: upcast from E* to A* might use path E* ! D* ! A* 649 | // but D is not constructed 650 | 651 | // “D((C*)this)” would be defined: E* ! C* is defined because E() has started, 652 | // and C* ! A* is defined because C is fully constructed 653 | 654 | X(this) {} // defined: upon construction of X, C/B/D/A sublattice is fully constructed. 655 | }; 656 | ``` 657 | - [Examples live](https://godbolt.org/z/Xu8yOi) 658 | 659 | - To form a pointer to (or access the value of) a direct non-static member of an object obj, the construction of obj shall have started and its destruction shall not have completed, otherwise the computation of the pointer value (or accessing 660 | the member value) results in undefined behavior. 661 | - [\[class.cdtor\]p3](http://eel.is/c++draft/class.cdtor#3) 662 | - Examples: 663 | ```cpp 664 | struct A { 665 | int x; 666 | }; 667 | 668 | void f() { 669 | A a; 670 | a.~A(); 671 | int *p=&a.x; // Destruction completed so computing the pointer is undefined behavior 672 | } 673 | ``` 674 | - [Examples lives](https://godbolt.org/z/O89aee) 675 | 676 | - If the virtual function call uses an explicit class member access (7.6.1.4) and the object expression refers to the complete 677 | object of x or one of that object’s base class subobjects but not x or one of its base class subobjects, the 678 | behavior is undefined. 679 | - [\[class.cdtor\]p4](http://eel.is/c++draft/class.cdtor#4) 680 | - Examples: 681 | ```cpp 682 | struct V { 683 | virtual void f(); 684 | virtual void g(); 685 | }; 686 | 687 | struct A : virtual V { 688 | virtual void f(); 689 | }; 690 | 691 | struct B : virtual V { 692 | virtual void g(); 693 | B(V*, A*); 694 | }; 695 | 696 | struct D : A, B { 697 | virtual void f(); 698 | virtual void g(); 699 | D() : B((A*)this, this) { } 700 | }; 701 | 702 | B::B(V* v, A* a) { 703 | f(); // calls V::f, not A::f 704 | g(); // calls B::g, not D::g 705 | v->g(); // v is base of B, the call is well-defined, calls B::g 706 | a->f(); // undefined behavior, a’s type not a base of B. 707 | } 708 | ``` 709 | - [Examples live](https://godbolt.org/z/-U8W-2) 710 | 711 | - If the operand of typeid refers to the object under construction or destruction and the static type of the operand is neither the constructor or destructor’s class nor one of its bases, the behavior is undefined 712 | - [\[class.cdtor\]p5](http://eel.is/c++draft/class.cdtor#5) 713 | - Examples: 714 | ```cpp 715 | struct V { 716 | virtual void f(); 717 | }; 718 | 719 | struct A : virtual V { }; 720 | struct B : virtual V { 721 | B(V*, A*); 722 | }; 723 | 724 | struct D : A, B { 725 | D() : B((A*)this, this) { } 726 | }; 727 | 728 | B::B(V* v, A* a) { 729 | typeid(*this); // type_info for B. 730 | typeid(*v); // well-defined: *v has type V, a base of B yields type_info for B 731 | typeid(*a); // undefined behavior: type A not a base of B 732 | dynamic_cast(v); // well-defined: v of type V*, V base of B results in B* 733 | dynamic_cast(a); // undefined behavior, a has type A*, A not a base of B 734 | } 735 | ``` 736 | - [Examples live](https://godbolt.org/z/XH7xat) 737 | 738 | - If the operand of the dynamic_cast refers to the object under construction or destruction and the static type 739 | of the operand is not a pointer to or object of the constructor or destructor’s own class or one of its bases, 740 | the dynamic_cast results in undefined behavior 741 | - [\[class.cdtor\]p6](http://eel.is/c++draft/class.cdtor#6) 742 | - Examples: 743 | ```cpp 744 | struct V { 745 | virtual void f(); 746 | }; 747 | 748 | struct A : virtual V { }; 749 | struct B : virtual V { 750 | B(V*, A*); 751 | }; 752 | 753 | struct D : A, B { 754 | D() : B((A*)this, this) { } 755 | }; 756 | 757 | B::B(V* v, A* a) { 758 | typeid(*this); // type_info for B. 759 | typeid(*v); // well-defined: *v has type V, a base of B yields type_info for B 760 | typeid(*a); // undefined behavior: type A not a base of B 761 | dynamic_cast(v); // well-defined: v of type V*, V base of B results in B* 762 | dynamic_cast(a); // undefined behavior, a has type A*, A not a base of B 763 | } 764 | ``` 765 | - [Examples live](https://godbolt.org/z/XH7xat) 766 | -------------------------------------------------------------------------------- /basic_def_odr.md: -------------------------------------------------------------------------------- 1 | - There can be more than one definition of a class type (Clause 12), enumeration type (10.2), inline function with external linkage (10.1.6), inline variable with external linkage (10.1.6), class template (Clause 17), non-static function template (17.6.6), concept (17.6.8), static data member of a class template (17.6.1.3), member function of a class template (17.6.1.1), or template specialization for which some template parameters are not specified (17.8, 17.6.5) in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements. Given such an entity named D defined in more than one translation unit, then ... If the definitions of D do not satisfy these requirements, then the behavior is undefined. *\[basic.def.odr\]/p12* 2 | - [Examples from: DCL60-CPP. Obey the one-definition rule](https://wiki.sei.cmu.edu/confluence/display/cplusplus/DCL60-CPP.+Obey+the+one-definition+rule) 3 | 4 | ```cpp 5 | // a.cpp 6 | struct S { 7 | int a; 8 | }; 9 | 10 | // b.cpp 11 | // S in b.cpp does not consist of the same sequence of token as S in a.cpp 12 | class S { 13 | public: 14 | int a; 15 | }; 16 | ``` 17 | 18 | 19 | ```cpp 20 | const int n = 42; 21 | 22 | int g(const int &lhs, const int &rhs); 23 | 24 | inline int f(int k) { 25 | return g(k, n); // f() has external linkage 26 | // n has internal linkage but is our-used by g() 27 | // n will not be identical in all transition units 28 | } 29 | ``` 30 | 31 | 32 | 33 | - Rationale: 34 | - [Devirtualization in C++, part 7 (Enforcing One Definition Rule) ](http://hubicka.blogspot.com/2014/09/devirtualization-in-c-part-6-enforcing.html) 35 | 36 | -------------------------------------------------------------------------------- /basic_indet.md: -------------------------------------------------------------------------------- 1 | - If an indeterminate value is produced by an evaluation, the behavior is undefined except in the following 2 | cases ... \[basic.indet\]p2 3 | - Example 4 | ```cpp 5 | int f(bool b) { 6 | unsigned char c; 7 | unsigned char d = c; // OK, d has an indeterminate value 8 | int e = d; // undefined behavior 9 | return b ? d : 0; // undefined behavior if b is true 10 | } 11 | ``` 12 | - Rationale 13 | - [WG14 Defect report 260](http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_260.htm) 14 | - [WG14 Defect report 451](http://www.open-std.org/Jtc1/sc22/WG14/www/docs/dr_451.htm) 15 | - Tl;DR; We have two case one in which using an indeterminate value is undefined behavior and this is because many type can have trap representations and using these value are undefined behavior. In the case of narrow character types the underlying values and type representation are one to one and therefore we don’t have a trap representation but they do retain their indeterminateness. 16 | -------------------------------------------------------------------------------- /basic_life.md: -------------------------------------------------------------------------------- 1 | - A program may end the lifetime of any object by reusing the storage which the object occupies or by explicitly calling the 2 | destructor for an object of a class type with a non-trivial destructor. For an object of a class type with a non-trivial destructor, 3 | the program is not required to call the destructor explicitly before the storage which the object occupies is reused or released; 4 | however, **if there is no explicit call to the destructor or if a delete-expression ([expr.delete]) is not used to release the storage, 5 | the destructor shall not be implicitly called and any program that depends on the side effects produced by the destructor has undefined behavior.** 6 | - [Pull request 2342 indicates this may not be undefined behavior at all](https://github.com/cplusplus/draft/pull/2342) and seeks the following edit
7 | implicitly called and any program that depends on the side effects produced by the destructor has undefined behaviorimplicitly called. 8 | -------------------------------------------------------------------------------- /basic_start.md: -------------------------------------------------------------------------------- 1 | 2 | - A hosted implementation shall contain a global function called main in one of the specified forms *\[basic.start.main\]* 3 | - 6.8.3.1 4 | - Example: 5 | 6 | ```cpp 7 | void main() {} 8 | ``` 9 | - Rationale: 10 | 11 | - Tools 12 | - [Compiler static analysis, generates warnings or errors for void main](https://wandbox.org/permlink/9YlvHEA88lS0CbvV) 13 | 14 | - The function main shall not be used within a program *\[basic.start.main\]* 15 | - 6.8.3.1 16 | - Examples: 17 | - [Is it illegal to take address of main() function?](https://stackoverflow.com/q/15525613/1708801) 18 | - [Why does gcc warn about decltype(main()) but not clang?](https://stackoverflow.com/q/25297257/1708801) 19 | 20 | ```cpp 21 | printf( “%p\n”, &main ) ; 22 | decltype(main()) x = 0; 23 | ``` 24 | 25 | ```cpp 26 | int main() { 27 | std::cout << reinterpret_cast(&main) ; 28 | } 29 | ``` 30 | 31 | - Tools 32 | - [Compiler static analysis via -pedantic flag gcc/clang for taking address of main](https://wandbox.org/permlink/atm7dJ1LXaVBkCsU) 33 | - [Compiler static analysis via -pedantic flag gcc/clang decltype main](https://wandbox.org/permlink/WvPFbU4hteDOX4w2) 34 | 35 | - Rationale: 36 | - From ARM section 3.4 Start and Termination 37 | > This is to ensure full freedom of the implementation of the interface between a C++ program and its environment. 38 | > One could imagine an implementation where main() was not implemented as a function. 39 | - [\[ub\] What does "The function main shall not be used within a program" mean?](http://www.open-std.org/pipermail/ub/2014-January/000474.html) 40 | 41 | -------------------------------------------------------------------------------- /lex_phases.md: -------------------------------------------------------------------------------- 1 | - if a splice results in a character sequence that matches the syntax of a universal-character-name, the behavior is undefined. *\[lex.phases\]/p2* 2 | - Example from [Stacoverflow question](https://stackoverflow.com/q/43824729/1708801): 3 | 4 | ```cpp 5 | const char* p = "\\ 6 | u0041"; 7 | ``` 8 | 9 | - Rationale 10 | - [DR 787](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#787) 11 | - [N3881 “Fixing the specification of universal-character-names”](http://open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3881.pdf) 12 | 13 | - If a character sequence that matches the syntax of a universal-character-name is produced by token concatenation (19.3.3), the behavior is undefined. *\[lex.phases\]/p4* 14 | - example: 15 | 16 | ```cpp 17 | #define GUARD_NAME ï ## _GUARD // UB per current spec 18 | #define COLUMN "ï" ## _column // UB per current spec 19 | ``` 20 | 21 | - Rationale 22 | - [DR 787](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#787) 23 | - [N3881 “Fixing the specification of universal-character-names”](http://open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3881.pdf) 24 | 25 | -------------------------------------------------------------------------------- /lex_pptoken.md: -------------------------------------------------------------------------------- 1 | - A preprocessing token is the minimal lexical element of the language in translation phases 3 through 6. … If a **’** or a **"** character matches the last category, the behavior is undefined. *\[lex.pptoken\]/p2* 2 | - Example [Why can't we use the preprocessor to create custom-delimeted strings?](https://stackoverflow.com/q/16798853/1708801) 3 | 4 | ```cpp 5 | #define STR_START " 6 | #define STR_END " 7 | 8 | int puts(const char *); 9 | 10 | int main() { 11 | puts(STR_START hello world STR_END); 12 | } 13 | ``` 14 | 15 | - Discussion 16 | - [Should it be ill-formed](https://groups.google.com/a/isocpp.org/forum/#!msg/std-discussion/lk1qAvCiviY/Zer-8iL88rUJ) 17 | - Rationale 18 | - Preprocessing token are generated during phase 3 so string and character literals as well and header names are identified at this point. both ‘ and “ would only be valid as part of one of these tokens, any left over after this point perhaps as part of a macro would not be valid since they could not tokenized as needed anymore. Macros are expanded as part of phase 4. 19 | 20 | -------------------------------------------------------------------------------- /lex_string.md: -------------------------------------------------------------------------------- 1 | - The effect of attempting to modify a string literal is undefined 2 | - Example: 3 | 4 | ```cpp 5 | const char *p1 = "hello world\n"; 6 | char *p2 = const_cast(p1) ; // const_cast is already suspicious 7 | 8 | p2[0] = 'm' ; 9 | ``` 10 | 11 | - Rationale *\[lex.string\]p8 12 | > Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow 13 | string literal **has type “array of n const char”**, where n is the size of the string as defined below, and has 14 | static storage duration (6.6.4). 15 | --------------------------------------------------------------------------------