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:
        ret
 
Reference: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.