public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Question related to changes in template handling
       [not found] <786553971.2049625.1653240191948.ref@mail.yahoo.com>
@ 2022-05-22 17:23 ` Klaus Lindemann
  2022-05-22 18:23   ` Jonathan Wakely
  0 siblings, 1 reply; 3+ messages in thread
From: Klaus Lindemann @ 2022-05-22 17:23 UTC (permalink / raw)
  To: gcc-help

Hello,
was the handling of templates changed for g++12? I've run across some programs
which did compile with e.g. g++8, g++11, but no longer compile with g++12.
The fix is quite easy, but I wonder if this change is a bug, or a more strict
implementation of the standard.
Here is a short example program:================================================// compiles with g++ 11, not g++ 12
#include <vector>namespace NN   // if namespace is removed (i.e. global namespace is used), problem does not occur{  class OStr {};}
template <class T> NN::OStr& operator<<(NN::OStr& lhs, const std::vector<T>& rhs) { return lhs << rhs[0]; }
// moving this definition before the other template definition fixes gcc 12 compile problemtemplate <class T> NN::OStr& operator<< (NN::OStr& lhs, const T& rhs) { return lhs << rhs; }
int main(){   std::vector<int> a;   NN::OStr os;   os << a;   return 0;}=================================================
Regards
Klaus

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Question related to changes in template handling
  2022-05-22 17:23 ` Question related to changes in template handling Klaus Lindemann
@ 2022-05-22 18:23   ` Jonathan Wakely
  2022-05-22 22:40     ` Klaus Lindemann
  0 siblings, 1 reply; 3+ messages in thread
From: Jonathan Wakely @ 2022-05-22 18:23 UTC (permalink / raw)
  To: Klaus Lindemann; +Cc: gcc-help

On Sun, 22 May 2022 at 18:25, Klaus Lindemann via Gcc-help
<gcc-help@gcc.gnu.org> wrote:
>
> Hello,
> was the handling of templates changed for g++12? I've run across some programs
> which did compile with e.g. g++8, g++11, but no longer compile with g++12.
> The fix is quite easy, but I wonder if this change is a bug, or a more strict
> implementation of the standard.
> Here is a short example program:================================================// compiles with g++ 11, not g++ 12
> #include <vector>namespace NN   // if namespace is removed (i.e. global namespace is used), problem does not occur{  class OStr {};}
> template <class T> NN::OStr& operator<<(NN::OStr& lhs, const std::vector<T>& rhs) { return lhs << rhs[0]; }
> // moving this definition before the other template definition fixes gcc 12 compile problemtemplate <class T> NN::OStr& operator<< (NN::OStr& lhs, const T& rhs) { return lhs << rhs; }
> int main(){   std::vector<int> a;   NN::OStr os;   os << a;   return 0;}=================================================


Reformatted so it's not illegible:

#include <vector>
namespace NN
// if namespace is removed (i.e. global namespace is used),
// problem does not occur
{
  class OStr {};
}
template <class T>
NN::OStr& operator<<(NN::OStr& lhs, const std::vector<T>& rhs)
{ return lhs << rhs[0]; }
// moving this definition before the other template definition
// fixes gcc 12 compile problem
template <class T>
NN::OStr& operator<< (NN::OStr& lhs, const T& rhs) { return lhs << rhs; }

int main(){
  std::vector<int> a;
  NN::OStr os;
  os << a;
  return 0;
}

GCC 12 is correct. Your code is wrong.

In the expression lhs << rhs[0], name lookup is done for operator<< by
considering the overloads already visible at that point, and overloads
that can be found by ADL in the associated namespaces. The associated
namespaces for OStr and int are NN, and there is no viable overload in
namepace NN.

An operator that is part of the API of NN::OStr should be defined in
namespace NN, not the global namespace. If you define both your
operator<< overloads in the same namespace as class OStr it will work.

N.B. this lookup is consistent for the non-template case, because GCC
12 has been fixed to stop looking in the global namespace when that is
not an associated namespace.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Question related to changes in template handling
  2022-05-22 18:23   ` Jonathan Wakely
@ 2022-05-22 22:40     ` Klaus Lindemann
  0 siblings, 0 replies; 3+ messages in thread
From: Klaus Lindemann @ 2022-05-22 22:40 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: gcc-help

 Thanks, this clears things up (sorry for the botched formatting of the original mail).This also explains why clang handles the code the same way as g++12.
Regards
Klaus
    Am Sonntag, 22. Mai 2022, 20:22:28 MESZ hat Jonathan Wakely <jwakely.gcc@gmail.com> Folgendes geschrieben:  
 
 On Sun, 22 May 2022 at 18:25, Klaus Lindemann via Gcc-help
<gcc-help@gcc.gnu.org> wrote:
>
> Hello,
> was the handling of templates changed for g++12? I've run across some programs
> which did compile with e.g. g++8, g++11, but no longer compile with g++12.
> The fix is quite easy, but I wonder if this change is a bug, or a more strict
> implementation of the standard.
> Here is a short example program:================================================// compiles with g++ 11, not g++ 12
> #include <vector>namespace NN  // if namespace is removed (i.e. global namespace is used), problem does not occur{  class OStr {};}
> template <class T> NN::OStr& operator<<(NN::OStr& lhs, const std::vector<T>& rhs) { return lhs << rhs[0]; }
> // moving this definition before the other template definition fixes gcc 12 compile problemtemplate <class T> NN::OStr& operator<< (NN::OStr& lhs, const T& rhs) { return lhs << rhs; }
> int main(){  std::vector<int> a;  NN::OStr os;  os << a;  return 0;}=================================================


Reformatted so it's not illegible:

#include <vector>
namespace NN
// if namespace is removed (i.e. global namespace is used),
// problem does not occur
{
  class OStr {};
}
template <class T>
NN::OStr& operator<<(NN::OStr& lhs, const std::vector<T>& rhs)
{ return lhs << rhs[0]; }
// moving this definition before the other template definition
// fixes gcc 12 compile problem
template <class T>
NN::OStr& operator<< (NN::OStr& lhs, const T& rhs) { return lhs << rhs; }

int main(){
  std::vector<int> a;
  NN::OStr os;
  os << a;
  return 0;
}

GCC 12 is correct. Your code is wrong.

In the expression lhs << rhs[0], name lookup is done for operator<< by
considering the overloads already visible at that point, and overloads
that can be found by ADL in the associated namespaces. The associated
namespaces for OStr and int are NN, and there is no viable overload in
namepace NN.

An operator that is part of the API of NN::OStr should be defined in
namespace NN, not the global namespace. If you define both your
operator<< overloads in the same namespace as class OStr it will work.

N.B. this lookup is consistent for the non-template case, because GCC
12 has been fixed to stop looking in the global namespace when that is
not an associated namespace.
  

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-05-22 22:40 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <786553971.2049625.1653240191948.ref@mail.yahoo.com>
2022-05-22 17:23 ` Question related to changes in template handling Klaus Lindemann
2022-05-22 18:23   ` Jonathan Wakely
2022-05-22 22:40     ` Klaus Lindemann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).