Re: Possible GCC optimization bug

Anubis 1101 via Gcc-help <[email protected]> Thu, 12 Feb 2026 18:46:46 +0000
Newsgroups gmane.comp.gcc.help
Message-ID <pe4tsx26O5j3kC_c5lHg9C1cIpB5FRshp4eFCRn9XH_Wf7BLPNDmwNUvhovVibftjGgC53VRmB00V2Wnpj-FWpIe_t28gMi8LN2uQ6-J4GM=@pm.me>
You were on the money. I both made a manual memory version (_bySize) and did the [Capaciy+1]
thing you suggested, and it fixed the problem in each case individually, and together. I 
didn't even have to change size() or length()'s formulae, since they're basically what strlen()
does under the hood anyway. Interestingly, replacing them with strlen() versions returned the
same value, but fixed the indexing issue! I would rather use explicit formulae though, so I'll
keep my original versions.
In any case, here's the code with the fixes, for reference: https://godbolt.org/z/6YvWoKKx1

I think I'll keep the original iteration version of concatenate(char) so that it doesn't
need to be fussed over when the size of char changes, at least for now. I'll have to keep in mind
that optimized indexing thing for future reference. I'm pretty good about UB in production
code, but that's a footgun I'm likely to shoot myself with, especially when I think I'm being
clever.

Thanks for the help!



On Thursday, February 12th, 2026 at 11:25 AM, Anubis 1101 <[email protected]> wrote:

> > Yes, and 'i' is "known" at compile-time to be < 10 due to the mechanism
> > I described earlier.  This is due to inlining.  Take the following
> > simplified example:
> >
> >   int i = /* doesn't matter */;
> >   int a[10] = /* doesn't matter */;
> >   print(a[i]);
> >   /* here, the compiler knows i < 10 due to a[i].  */
> >
> > This is essentially what happens in your example also.  The compiler did
> > a lot of inlining to turn multiple functions into one single function
> > that has pretty much the same pattern as the above in it.  It is
> > permitted to do that.  It can, in fact, copy length and operator[] into
> > other functions that use them as many times as it likes, as long as it
> > still behaves the same as the abstract machine of the language requires.
> 
> I did not know about that, that's interesting stuff!
> But the const char* version works, so I'll look into that. I figured it was
> inlining the wrong value, but even if I replaced both size() and length() with
> strlen(), the measured value was the same, so I figured that couldn't be it.
> Perhaps the const char* version works because it's using manual memory
> calculation?
> 
> I'll have to do some messing around and see what I can find out.
> 
> 
> On Thursday, February 12th, 2026 at 10:59 AM, Arsen Arsenović <[email protected]> wrote:
> 
> > Anubis 1101 <[email protected]> writes:
> >
> > > 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.
> >
> > Yes, and 'i' is "known" at compile-time to be < 10 due to the mechanism
> > I described earlier.  This is due to inlining.  Take the following
> > simplified example:
> >
> >   int i = /* doesn't matter */;
> >   int a[10] = /* doesn't matter */;
> >   print(a[i]);
> >   /* here, the compiler knows i < 10 due to a[i].  */
> >
> > This is essentially what happens in your example also.  The compiler did
> > a lot of inlining to turn multiple functions into one single function
> > that has pretty much the same pattern as the above in it.  It is
> > permitted to do that.  It can, in fact, copy length and operator[] into
> > other functions that use them as many times as it likes, as long as it
> > still behaves the same as the abstract machine of the language requires.
> >
> > In fact, 'if (i < Capacity)' probably never happens.  The compiler
> > deduces that it is true due to the array accesses.
> > --
> > Arsen Arsenović
> >