Reference:
Both true and false: a Zen moment with C
asm: test instruction:
https://web.itu.edu.tr/kesgin/mul06/intel/instr/test.html
asm: SETNE instruction :
https://web.itu.edu.tr/kesgin/mul06/intel/instr/setne_setnz.html
code:
Undefined behavior can result in time travel
If there's an UB in code path, compiler could consider all code paths go to one code path.
code:
inference:
A post-classical compiler, on the other hand, might perform the following analysis:
to code:
Reference:
What Every C Programmer Should Know About Undefined Behavior #1/3
What Every C Programmer Should Know About Undefined Behavior #2/3
What Every C Programmer Should Know About Undefined Behavior #3/3
A Guide to Undefined Behavior in C and C++, Part 1
A Guide to Undefined Behavior in C and C++, Part 2
A Guide to Undefined Behavior in C and C++, Part 3
UBs:
Reference:
Adventures in undefined behavior: The premature downcast
"If a nonstatic member function of a class X is called for an object that is not of type X, or of a type derived from X, the behavior is undefined."
In other words, if you are invoking a method on an object of type X, then you are promising that it really is of type X, or a class derived from it.
code:
Reference:
A static_cast is not always just a pointer adjustment
The rule for null pointers is that casting a null pointer to anything results in another null pointer.
Reference:
A bit of background on compilers exploiting signed overflow
------------
For infinite loop, compiler should not opt out in these conditions:
The implementation may assume that any thread will eventually do one of the following:
Empty infinite loops are UB in C++11 and later.
Reference:
Compilers and Termination Revisited
Is this infinite recursion UB?
Optimizing away a “while(1);” in C++0x
is C implementation allowed to terminate an infinite loop?
[rust] LLVM loop optimization can make safe programs crash
--
Principles for Undefined Behavior in Programming Language Design - John Regehr
Both true and false: a Zen moment with C
asm: test instruction:
https://web.itu.edu.tr/kesgin/mul06/intel/instr/test.html
asm: SETNE instruction :
https://web.itu.edu.tr/kesgin/mul06/intel/instr/setne_setnz.html
code:
#include <stdio.h> #include <stdbool.h> int main(int argc, char *argv[]) { volatile bool p; if ( p ) puts("p is true"); else puts("p is not true"); if ( ! p ) puts("p is false"); else puts("p is not false"); return 0; }asm code:
.file "bool1.c" .intel_syntax noprefix .section .rodata .LC0: .string "p is true" .LC1: .string "p is not true" .LC2: .string "p is false" .LC3: .string "p is not false" .text .globl main .type main, @function main: .LFB0: push rbp .LCFI0: mov rbp, rsp .LCFI1: sub rsp, 32 .LCFI2: mov DWORD PTR [rbp-20], edi mov QWORD PTR [rbp-32], rsi movzx eax, BYTE PTR [rbp-1] test al, al je .L2 mov edi, OFFSET FLAT:.LC0 call puts jmp .L3 .L2: mov edi, OFFSET FLAT:.LC1 call puts .L3: movzx eax, BYTE PTR [rbp-1] xor eax, 1 // HERE, since local variable isn't init., the value could be other value than 1. // Thus, an XOR will always produce True. test al, al je .L4 mov edi, OFFSET FLAT:.LC2 call puts jmp .L5 .L4: mov edi, OFFSET FLAT:.LC3 call puts .L5: mov eax, 0 leave .LCFI3: retReference:
Undefined behavior can result in time travel
If there's an UB in code path, compiler could consider all code paths go to one code path.
code:
int table[4]; bool exists_in_table(int v) { for (int i = 0; i <= 4; i++) { if (table[i] == v) return true; } return false; }
inference:
A post-classical compiler, on the other hand, might perform the following analysis:
- The first four times through the loop, the function might return true.
- When i is 4, the code performs undefined behavior.
- Since undefined behavior lets me do anything I want, I can totally ignore that case and proceed on the assumption that i is never 4. (If the assumption is violated, then something unpredictable happens, but that’s okay, because undefined behavior grants me permission to be unpredictable.)
- The case where i is 5 never occurs, because in order to get there, I first have to get through the case where i is 4, which I have already assumed cannot happen.
- Therefore, all legal code paths return true.
to code:
bool exists_in_table(int v) { return true; }
Reference:
What Every C Programmer Should Know About Undefined Behavior #1/3
What Every C Programmer Should Know About Undefined Behavior #2/3
What Every C Programmer Should Know About Undefined Behavior #3/3
A Guide to Undefined Behavior in C and C++, Part 1
A Guide to Undefined Behavior in C and C++, Part 2
A Guide to Undefined Behavior in C and C++, Part 3
- Interacting Compiler Optimizations Lead to Surprising Results
- Undefined Behavior and Security Don't Mix Well
- Debugging Optimized Code May Not Make Any Sense.
- "Working" code that uses undefined behavior can "break" as the compiler evolves or changes
- There is No Reliable Way to Determine if a Large Codebase Contains Undefined Behavior
UBs:
- Use of an uninitialized variable
- Signed integer overflow
- Oversized Shift Amounts
- Dereferences of Wild Pointers and Out of Bounds Array Accesses
- Dereferencing a NULL Pointer
- Violating Type Rules
- It is undefined behavior to cast an int* to a float* and dereference it (accessing the "int" as if it were a "float").
Reference:
Adventures in undefined behavior: The premature downcast
"If a nonstatic member function of a class X is called for an object that is not of type X, or of a type derived from X, the behavior is undefined."
In other words, if you are invoking a method on an object of type X, then you are promising that it really is of type X, or a class derived from it.
code:
class Shape { public: virtual bool Is2D() { return false; } }; class Shape2D : public Shape { public: virtual bool Is2D() { return true; } }; Shape *FindShape(Cookie cookie); void BuyPaint(Cookie cookie) { Shape2D *shape = static_cast<Shape2D *>(FindShape(cookie)); if (shape->Is2D()) { // ALWAYS TRUE! Since it's the type of Shape2D .. do all sorts of stuff ... } }
Reference:
A static_cast is not always just a pointer adjustment
The rule for null pointers is that casting a null pointer to anything results in another null pointer.
Reference:
A bit of background on compilers exploiting signed overflow
------------
For infinite loop, compiler should not opt out in these conditions:
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.
Empty infinite loops are UB in C++11 and later.
Reference:
Compilers and Termination Revisited
Is this infinite recursion UB?
Optimizing away a “while(1);” in C++0x
is C implementation allowed to terminate an infinite loop?
[rust] LLVM loop optimization can make safe programs crash
--
Principles for Undefined Behavior in Programming Language Design - John Regehr
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.