On Thu, Jul 11, 2024 at 5:04 PM Dalbey, Keith via Gcc <gcc@gcc.gnu.org> wrote:
>
> So I'm on redhat 7 and just got devtoolsset-12 and code (a system of 
> overloaded<< operators) that was working with devtoolset-10 now break 
> (because of ordering)
>
> To not bury the lead..
>
> My code relies on the version 11 or older behavior (see below), and I don't 
> see how anyone could call the new behavior an improvement or correction 
> because it neuters/cancels out  the power/flexibility of the STL.   Yes one 
> could technically work around it by forward declaring templated operator<<  
> but that makes the system not extensible,  a common package/gitlab project 
> that handles this for the STL and then gets succeed into another library that 
> overloads the operator<< for concrete classes just doesn't work any more... 
> and that was my exact use case.

So your code depends on non-standard behavior that GCC accidentally
got wrong until GCC 12.
I feel for you but ...

>
> Please reverse this change in future editions of gcc, it is absolutely awful.

This is not going to happen since your code depended on incorrect
behavior. And code that depends on behavior defined by the standard
would now break.

Thanks,
Andrew

>
> From this link
> https://developers.redhat.com/articles/2022/04/25/new-c-features-gcc-12#corrections_and_internal_improvements
> Corrections and internal improvements
> The changes described in this section bring GCC more in line with recent 
> changes to the standard, and permit behavior that previously did not work 
> correctly.
> Dependent operator lookup changes
> GCC 12 corrected a problem where the compiler performed an unqualified lookup 
> for a dependent operator expression at template definition time instead of at 
> instantiation time. The fix matches the existing behavior for dependent call 
> expressions. Consider the following test case demonstrating this change:
> #include <iostream>
>
> namespace N {
>   struct A { };
> }
>
> void operator+(N::A, double) {
>   std::cout << "#1 ";
> }
>
> template<class T>
> void f(T t) {
>   operator+(t, 0);
>   t + 0;
> }
>
> // Since it's not visible from the template definition, this later-declared
> // operator overload should not be considered when instantiating 
> f<N::A>(N::A),
> // for either the call or operator expression.
> void operator+(N::A, int) {
>   std::cout << "#2 ";
> }
>
> int main() {
>   N::A a;
>   f(a);
>   std::cout << std::endl;
> }
> Copy snippet
> This program will print #1 #2 when compiled with versions 11 or older of GCC, 
> but GCC 12 correctly prints #1 #1. That's because previously only the call 
> expression resolved to the #1 overload, but with GCC 12 the operator 
> expression does too.

Reply via email to