<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sun, Aug 10, 2014 at 7:10 AM, Nicola Gigante <span dir="ltr"><<a href="mailto:nicola.gigante@gmail.com" target="_blank">nicola.gigante@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Hello.<br>
<br>
While testing a recently written piece of code to see if it worked on linux<br>
I found three differences between clang and g++ that make the first<br>
to compile the code and the second to reject it. I'm talking about the<br>
clang shipped with Xcode 5.1.1, I don't have a working trunk and my<br>
machine is slow to compile, sorry.<br>
<br>
Below the three issues:<br>
<br>
1) transitive-friend.cpp<br>
class A {<br>
  friend class B;<br>
  int v;<br>
};<br>
<br>
struct B {<br>
  A a;<br>
  friend int f(B b) {<br>
     return b.a.v;<br>
  }<br>
};<br>
<br>
Clang accept this code because<br>
I access the private field of A in the scope of B<br>
and B is a friend. g++ rejects it:<br>
<br>
$ g++-4.9 -std=c++11 -fsyntax-only differences.cpp<br>
differences.cpp: In function 'int f(B)':<br>
differences.cpp:3:7: error: 'int A::v' is private<br>
   int v;<br>
       ^<br>
differences.cpp:9:17: error: within this context<br>
      return b.a.v;<br>
                 ^<br></blockquote><div><br></div><div>Clang's behavior reflects the current intent of the C++ core working group. This is core issue 1699, and the current resolution to that is to treat everything that is lexically within a befriended entity as being befriended. GCC does not yet implement the resolution to core issue 1699 (which is reasonable, since it's not yet even resolved).</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
2) templatebase.cpp<br>
template<typename T><br>
struct A {<br>
   template<typename U><br>
   struct B {<br>
<br>
   };<br>
<br>
   struct C;<br>
};<br>
<br>
template<typename T><br>
struct A<T>::C : public A<T>::B<int> // public A<T>::template B<int><br>
{<br>
<br>
};<br>
<br>
Is the template keyword needed here?</blockquote><div><br></div><div>Clang's behavior reflects the current intent of the C++ core working group. This is core issue 1710 (which Clang only partially follows); the template keyword is optional in this context.<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Note that if you move out<br>
struct C so that it isn't a member of A anymore, clang correctly<br>
says that I need the template keyword. g++ wants the keyword<br>
in both cases:<br>
<br>
$ g++-4.9 -std=c++11 -fsyntax-only templatebase.cpp<br>
templatebase.cpp:12:36: error: 'typename A<T>::B' names 'template<class T> template<class U> struct A<T>::B', which is not a type<br>
 struct A<T>::C : public A<T>::B<int> {<br>
                                    ^<br>
templatebase.cpp:12:31: error: 'typename A<T>::B' names 'template<class T> template<class U> struct A<T>::B', which is not a type<br>
 struct A<T>::C : public A<T>::B<int> {<br>
                               ^<br>
templatebase.cpp:12:38: error: expected class-name before '{' token<br>
 struct A<T>::C : public A<T>::B<int> {<br>
                                      ^<br>
3) tupleconstructor.cpp<br>
#include <tuple><br>
<br>
std::tuple<int, int, int><br>
func() {<br>
   return { 0, 1, 2 };<br>
}<br>
<br>
I don't know how to phrase the situation in standardese terms (is it list-initialization?).<br>
It seems to me that clang picks the forwarding constructor, g++ the explicit initializer-list constructor.<br></blockquote><div><br></div><div>Is this a Clang versus GCC issue, or a libc++ versus libstdc++ issue? What does Clang say if you use -stdlib=libstdc++? I would not be surprised if this is a library DR.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
$ g++-4.9 -std=c++11 -fsyntax-only tupleconstructor.cpp<br>
tupleconstructor.cpp: In function 'std::tuple<int, int, int> func()':<br>
tupleconstructor.cpp:5:21: error: converting to 'std::tuple<int, int, int>' from initializer list would use explicit constructor 'constexpr std::tuple< <template-parameter-1-1> >::tuple(_UElements&& ...) [with _UElements = {int, int, int}; <template-parameter-2-2> = void; _Elements = {int, int, int}]'<br>

    return { 0, 1, 2 };<br>
                     ^<br>
<br>
In all these three cases, who is right? Are these bugs in clang?<br>
In this case, should I make a separate bug report for each case, right? I've attached the single test cases<br>
<br>
Greetings,<br>
Nicola<br>
<br>
<br>
<br><br>
<br>
<br>_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@cs.uiuc.edu">cfe-dev@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a><br>
<br></blockquote></div><br></div></div>