├── LICENSE └── README.md /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # What is this repository for? 2 | 3 | This is a set of Undefined Behaviour C/C++ Snippets. It's, for now, a chaotic and really incomplete set of C/C++ snippets showing undefined behaviour without proper classification or explanations. Feel free to send pull requests making it more understandable or simply adding more. 4 | 5 | # Undefined Behaviour Snippets 6 | 7 | ## Division By Zero 8 | 9 | ``` 10 | int x = 1; 11 | return x / 0; // undefined behavior 12 | ``` 13 | 14 | ## Out-of-bounds operations 15 | 16 | Simple example 1: 17 | 18 | ``` 19 | int arr[4] = {0, 1, 2, 3}; 20 | int *p = arr + 5; // undefined behavior 21 | ``` 22 | 23 | Computing an out-of-bounds pointer is UB, even without dereferencing it: 24 | 25 | ``` 26 | short a[10]; 27 | short *p = &a[15]; // Bleep 28 | ``` 29 | 30 | ## Unrelated objects 31 | 32 | Comparing pointers from unrelated objects is UB in C: 33 | 34 | ``` 35 | long *p = malloc(size(long)); 36 | long *q = malloc(size(long)); 37 | if (p > q) ... // Ouch 38 | ``` 39 | 40 | ## Modifying an object between two sequence points 41 | 42 | Modifying an object between two sequence points more than once produces undefined behavior. It is worth mentioning that there are considerable changes in what causes undefined behavior in relation to sequence points as of C++11. The following example will however cause undefined behavior in both C++ and C. 43 | 44 | Example 1: 45 | ``` 46 | i = i++ + 1; // undefined behavior 47 | ``` 48 | 49 | Example 2: 50 | ``` 51 | a[i] = i++; // undefined behavior 52 | printf("%d %d\n", ++n, power(2, n)); // also undefined behavior 53 | ``` 54 | 55 | ## Arithmetic overflows 56 | 57 | Simple example: 58 | ``` 59 | #include 60 | #include 61 | 62 | int main (void) 63 | { 64 | printf ("%d\n", (INT_MAX+1) < 0); 65 | return 0; 66 | } 67 | ``` 68 | 69 | Real world example: 70 | ``` 71 | int64_t V = IV->getSExtValue(); 72 | if (V >= 0) 73 | Record.push_back(V << 1); 74 | else 75 | Record.push_back((-V << 1) | 1); <<----- bad line 76 | 77 | ``` 78 | 79 | The previous code causes this error: 80 | ``` 81 | UNDEFINED at : 82 | Operator: - 83 | Reason: Signed Subtraction Overflow 84 | left (int64): 0 85 | right (int64): -9223372036854775808 86 | ``` 87 | 88 | In all modern C/C++ variants running on two’s complement machines, negating an int whose value is INT_MIN (or in this case, INT64_MIN) is undefined behavior. The fix is to add an explicit check for this case. 89 | 90 | ## Uninitialized variables 91 | 92 | Reading an uninitialized local variable is usually UB: 93 | ``` 94 | int x; 95 | printf("%d", x); // UB happens here 96 | ``` 97 | 98 | ## Shifting more than the integer width or less than zero 99 | 100 | Shifting more than the integer width or less than zero is UB: 101 | ``` 102 | uint32_t x = 0; 103 | x = x << 33; // Blamo 104 | x = x >> (-1); // Kapow 105 | ``` 106 | 107 | ## Null pointers 108 | 109 | Suppose we have a piece of code like this: 110 | 111 | ``` 112 | void f(int *p) { 113 | printf("%d", *p); 114 | if (p != NULL) 115 | printf("OK"); 116 | } 117 | ``` 118 | 119 | Then the compiler is permitted to substitute this equivalent code with the null check removed: 120 | 121 | ``` 122 | void f(int *p) { 123 | printf("%d", *p); 124 | printf("OK"); 125 | } 126 | ``` 127 | 128 | Why? Suppose p is not NULL. Then the first print will be fine, and the second print will get executed. Now suppose p is 129 | NULL. Then the first print triggers UB, so everything thereafter is meaningless. For convenience we can make this behave the same as the first case, where both prints get executed. 130 | 131 | ## Order of parameters 132 | 133 | Example: 134 | 135 | ``` 136 | some_func(foo(), bar()); 137 | ``` 138 | 139 | It isn't guaranteed that foo() will be executed before bar() or the other way around. 140 | 141 | ## Assigning to a constant 142 | 143 | Assigning to a constant after stripping constness using const_cast: 144 | 145 | ``` 146 | const int i = 10; 147 | int *p = const_cast( &i ); 148 | *p = 1234; //Undefined 149 | ``` 150 | 151 | ## Copying between overlapping memory regions 152 | 153 | Using memcpy to copy between overlapping memory regions. For example: 154 | 155 | ``` 156 | char a[256] = {}; 157 | memcpy(a, a, sizeof(a)); 158 | ``` 159 | 160 | The behavior is undefined according to the C Standard, which is subsumed by the C++03 Standard. 161 | 162 | # References 163 | 164 | * [Wikipedia](https://en.wikipedia.org/wiki/Undefined_behavior) 165 | * [A Guide to Undefined Behavior in C and C++, Part 1](http://blog.regehr.org/archives/213) by John Regehr. 166 | * [Undefined behavior in C and C++ programs](https://www.nayuki.io/page/undefined-behavior-in-c-and-cplusplus-programs) from Project Nayuki. 167 | * [What are all the common undefined behaviours that a C++ programmer should know about?](http://stackoverflow.com/questions/367633/what-are-all-the-common-undefined-behaviours-that-a-c-programmer-should-know-a) in Stack Overflow. 168 | 169 | 170 | --------------------------------------------------------------------------------