Em seg., 31 de ago. de 2020 às 14:43, Ranier Vilela <ranier...@gmail.com>
escreveu:

> Em seg., 31 de ago. de 2020 às 14:00, Alvaro Herrera <
> alvhe...@2ndquadrant.com> escreveu:
>
>> On 2020-Aug-31, Ranier Vilela wrote:
>>
>> > More troubles with undefined-behavior.
>> >
>> > This type of code can leaves overflow:
>> > var = (cast) (expression);
>> > diff = (int32) (id1 - id2);
>> >
>> > See:
>> >     diff64 =  ((long int) d1 - (long int) d2);
>> >     diff64=-4294901760
>>
>> Did you compile this with gcc -fwrapv?
>>
> gcc 10.2 -O2  -fwrapv
> bool test1()
> {
>     unsigned int d1 = 3;
>     unsigned int d2 = 4294901763;
>     long int diff64 = 0;
>
>     diff64 =  ((long int) d1 - (long int) d2);
>
>     return (diff64 < 0);
> }
>
> output:
> mov     eax, 1
>         ret
>
> What is a workaround for msvc 2019 (64 bits) and clang 64 bits (linux)?
> transam.c:311:22: runtime error: unsigned integer overflow: 3 - 4294901763
> cannot be represented in type 'unsigned int'
>

with Debug:
#include <stdio.h>
#include <stdint.h>

bool test1(void)
{
    unsigned int d1 = 3;
    unsigned int d2 = 4294901763;
    int32_t diff;

    diff = (int32_t) (d1 - d2);

    return (diff < 0);
}

gcc 10.2 -g
output:
       push    rbp
        mov     rbp, rsp
        mov     DWORD PTR [rbp-4], 3
        mov     DWORD PTR [rbp-8], -65533
        mov     eax, DWORD PTR [rbp-4]
        sub     eax, DWORD PTR [rbp-8]
        mov     DWORD PTR [rbp-12], eax
        mov     eax, DWORD PTR [rbp-12]
        shr     eax, 31
        pop     rbp
        ret

it is possible to conclude that:
1. TransactionIdPrecedes works in release mode, because the compiler treats
undefined-behavior and corrects it,
treating a possible overflow.
2. TransactionIdPrecedes does not work in debug mode, and overflow occurs.
3. TransactionID cannot contain the largest possible ID or an invalid ID
(4294901763) has been generated and passed to TransactionIdPrecedes.

Ranier Vilela

Reply via email to