Re: Possible GCC optimization bug
Anubis 1101 via Gcc-help <[email protected]> Thu, 12 Feb 2026 17:46:49 +0000
| Newsgroups | gmane.comp.gcc.help |
|---|---|
| Message-ID | <n3Hmp_woKQRyXSO3IkJN57Hcpz2-0-u743NneZO77rd4SkpbYrbTA1QkgH9gVANVZM6yifo50u5N3QYB3h_e7ufRq6rf04j0-jQ51h9VPnk=@pm.me> |
If you think it's walking past the end of the array, you definitely didn't read it. I'm going to ignore you now until that changes. On Thursday, February 12th, 2026 at 10:43 AM, Jonathan Wakely <[email protected]> wrote: > On Thu, 12 Feb 2026 at 17:40, Anubis 1101 via Gcc-help <[email protected]> wrote: > >> That's some good insight, but that's not what's happening here. > > It is though. > >> You can manually verify for yourself that the terminator does in fact exist directly after the string. > > That's beside the point, it's a separate memory location, and walking off the end of the array is undefined behaviour. It doesn't matter what byte happens to come next in memory, the program has undefined behaviour, so it doesn't work how you want it to. > >> Even if it isn't guaranteed, it's not the bug here. > > The code has undefined behaviour. Insisting that something else is causing the problem is a waste of time, the compiler is not required to produce "correct" output for a program with undefined behaviour. > > Fix the UB, then see if there's still a problem. > >> "X", as you call it, is a constant named "available", initialized with the value of length(), which is basically strlen(). >> It takes the length at call time, stores it, and then uses it for if-statements. Problem is, the value >> appears to change. You can see this easily in the code, where it checks "available > 0", which passes, >> and then prints out "available", which is 0. >> >> The "10 < 10" comes from the subscript operator overload, where it checks the index against the Capacity, >> which is known at compile time. The "if(i < Capacity)" statement passes, and then prints out both i and Capacity, which >> are both 10. >> >> No matter how you look at it, something is very wrong here. > > It's your code, and apparently your willingness to learn how the language works. > >> On Thursday, February 12th, 2026 at 10:28 AM, Arsen Arsenović <[email protected]> wrote: >> >>> Anubis 1101 <[email protected]> writes: >>> >>> > That does appear to "fix" it, but it doesn't tell me what was actually >>> > wrong. It just corrects the bad addressing and additionally prints >>> > out "runtime error: index 10 out of bounds for type 'char >>> > [10]'"... which, yea, I know that. That's half of why I'm here. If >>> > there's something specific I'm doing that's causing it, that's what >>> > I'd like to know. As far as I can tell, there's no flaw in my code >>> > itself. >>> >>> It doesn't fix it. It demonstrates why your code is incorrect (at least >>> in this instance). >>> >>> GCC deduced that the "10 < 10" condition, as you named it, holds true, >>> because GCC deduced that the former 10 comes from a variable that is >>> used to access a loop of length 10. I didn't track down what variable >>> this is, so let's call it X for posterity. >>> >>> The language rules state that, for an array access expression a[i] where >>> 'a' is an array of length N, 'i' must be such that 0 <= i < N. >>> >>> Here, 'a' is 'data' and 'i' is X on lines 166 and 177 (fn:1). As a >>> result, GCC is allowed to assume that X < N. As N here was 10, X < 10, >>> leading to the 10 < 10 condition being "true". >>> >>> This is properly fixed by not allowing the loops in length and size >>> overrun the array; something like this: >>> >>> while (i < Capacity && data[i] != '\0'){i++;} >>> >>> Indeed, this fixes the UBSan warnings (note that the capacity check must >>> come first so that data[i] is not executed when i=Capacity). >>> >>> C and C++ are high-level programming languages. What you did here is >>> assume that term immediately follows data, and data[Capacity] is the >>> same as term. But, the language does not actually specify this, so you >>> can't do that. The ABI does specify this. But you're writing C++ >>> abstract machine code, so that doesn't matter. data[Capacity] is, in >>> fact, not a valid expression. >>> >>> The bug here is that GCC didn't catch and report this in a warning. >>> There's supposed to be a warning for this case. Not sure why it didn't >>> trigger. But definitely not incorrect codegen (and I can't debug the >>> warning at this exact moment, sorry). >>> >>> I recommend not separating 'term' out. Reserve Capacity+1, and write >>> logic that ensures there's always a terminator. >>> >>> Have a lovely day! >>> >>> [fn:1] Note that X here is not the 'i' used inside those loops. It is >>> whatever was downstream from the 'i' returned from those >>> functions. That's why I'm giving it the name X. >>> -- >>> Arsen Arsenović >>>