Re: Possible GCC optimization bug
Anubis 1101 via Gcc-help <[email protected]> Thu, 12 Feb 2026 10:25:45 +0000
| Newsgroups | gmane.comp.gcc.help |
|---|---|
| Message-ID | <wOpSn2QB8ps-DXSDBJHRAa3J1HPACC35tptESZVtcuZpxiiZ9ZN9Uxi4E_No9SHcdXMIWtwH9mKA5Ki6hwlH_YW6nYG8jUdWCnecdrc713U=@pm.me> |
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. 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?