Using gcc __uint128_t and later scanf of uint8_t lead to UB

Viewed 36

I've been playing around with __uint128_t in gcc and came across the fact that such code

#include <cstdio>
#include <cstdlib>
#include <cstdint>

int main()
{
    __uint128_t very_long = 1;
    std::uint8_t num;
    scanf("%u", &num);
    printf("%llu", static_cast<uint64_t>(very_long));
    return 0;
}

leads to different behaviour depending on the level of optimization. If compiled with -O0 it prints 0, whereas compiled with -O1, -O2 or -O3 it prints 1 as expected.

However if I enforce alignment, the result is 1 regardless of the optimization level.

#include <cstdio>
#include <cstdlib>
#include <cstdint>

int main()
{
    __uint128_t very_long = 1;
    std::uint8_t num __attribute__ ((aligned(4)));
    scanf("%u", &num);
    printf("%llu", static_cast<uint64_t>(very_long));
    return 0;
}

So the question is - is it some kind of a bug or am I missing something?

P.S. Used godbolt.org to compile, tried both x86-64 gcc 10.2 and x86-64 gcc 12.2 (--std=c++17 -OX)

0 Answers
Related