Re: Possible GCC optimization bug

Jonathan Wakely via Gcc-help <[email protected]> Thu, 12 Feb 2026 15:22:13 +0000
Newsgroups gmane.comp.gcc.help
Message-ID <CAH6eHdQG5=AC4P1qf7OtjsE7FhyNLbGbp+OemJE1hXKr54=CSw@mail.gmail.com>
On Thu, 12 Feb 2026 at 10:27, Anubis 1101 via Gcc-help <[email protected]>
wrote:

> Ah, yes, I was messing with it and must've forgotten to add that back in.
> Here's the corrected code: https://godbolt.org/z/E8Gsddb6G
>
> You're right though, that's not the bug, as it never reaches that
> statement. Something that simple would've been cleaned out in one of the
> other times I rewrote it.
>

As I already said in my first email, the bug is the undefined behaviour
that UBsan reports. Compile with -fsanitize=undefined and the bug is
diagnosed.



>
> Interestingly, when I wrote it using ternaries instead of regular if
> statements, it actually shorted the length and overwrote the last character
> in the string instead. If I manually increase it, it seems to behave as
> normal if there is extra room in the string, but if there is only one
> space, the compiler catches it as trying to write outside the string, even
> though it's the correct target going by the end result.
>
> On Thursday, February 12th, 2026 at 2:57 AM, Jonathan Wakely <
> [email protected]> wrote:
>
> > On Thu, 12 Feb 2026 at 01:02, Anubis 1101 via Gcc-help <
> [email protected]> wrote:
> >
> >> I've encountered some very strange behavior in this string class I'm
> working on, and I think I've narrowed it down to being a compiler bug.
> >> Here's the Godbolt link: https://godbolt.org/z/axPjzP1Eq
> >> All unnecessary members have been commented out, but left in for
> reference.
> >>
> >> The basic idea is that I'm measuring the free space between the current
> size of the string and the string's capacity, and then using that to
> properly concatenate a single char (conditionally followed by a terminator).
> >> However, the size check goes awry once it's inside an if() or switch()
> check, seemingly changing to the wrong value, and then changing back.
> Additionally, even if I abstract the subscript operation to the member
> function (which has its own explicit bounds checking), now THAT check fails
> as well, in the same way! It seems to happen most noticeably when
> 'available' is zero, but because this is a single-char concatenation, it's
> difficult to test it any other way (the const char* version after it has no
> such issues).
> >>
> >> constexpr simpleString& concatenate(constchar input)noexcept{
> >> const std::size_t currentLength = length();
> >> const std::size_t available = Capacity-currentLength;
> >>
> >> //the bug starts happening here, in this check
> >> if(available >0){
> >> std::cout <<"\n value is greater than zero. value: "<< available<<
> std::endl;
> >> this->operator[](currentLength)= input; //the bounds check inside this
> operator ALSO exhibits the bug
> >> }
> >> if(available >1){
> >> std::cout <<"\n value is greater than one. value: "<< available<<
> std::endl;
> >> this->operator[](currentLength)='\0';
> >> }
> >
> > If available is 2 then you append the character, then overwrite it with
> the null terminator. Should the nul be written to
> operator[](currentLength+1) instead?
> >
> > That's not the bug though.
> >
> >> return*this;}
> >> No amount of reformatting, code cleaning, code malformation, or
> misdirection seems to unstick this bug. I tried rewriting it in different
> ways, and even as a fallthrough switch statement, to no avail. Even if I
> removed all instances of UB and did everything explicitly, the behavior did
> not change. I've tried to isolate it by separating out the member function,
> but then the bug goes away; it only seems to happen in the context of this
> class. I've also never had this problem before in any other context, so I'm
> not sure how to narrow it down further. I'm not experienced enough with
> assembly to pinpoint exactly what's going wrong, either.
> >>
> >> The only thing that made any difference was dropping it to a lower
> optimization level. On -O1 and -O0, it works just fine, but -O2 and -O3, it
> expresses the bug.
> >> Am I just missing something really simple here, or is this a legitimate
> bug?