[cfe-dev] Three code snippets accepted by clang and rejected by g++

Nicola Gigante nicola.gigante at gmail.com
Sun Aug 10 07:10:00 PDT 2014


Hello.

While testing a recently written piece of code to see if it worked on linux
I found three differences between clang and g++ that make the first
to compile the code and the second to reject it. I'm talking about the
clang shipped with Xcode 5.1.1, I don't have a working trunk and my
machine is slow to compile, sorry.

Below the three issues:

1) transitive-friend.cpp
class A {
  friend class B;
  int v;
};

struct B {
  A a;
  friend int f(B b) {
     return b.a.v;
  }
};

Clang accept this code because
I access the private field of A in the scope of B
and B is a friend. g++ rejects it:

$ g++-4.9 -std=c++11 -fsyntax-only differences.cpp 
differences.cpp: In function 'int f(B)':
differences.cpp:3:7: error: 'int A::v' is private
   int v;
       ^
differences.cpp:9:17: error: within this context
      return b.a.v;
                 ^

2) templatebase.cpp
template<typename T>
struct A {
   template<typename U>
   struct B {

   };

   struct C;
};

template<typename T>
struct A<T>::C : public A<T>::B<int> // public A<T>::template B<int>
{

};

Is the template keyword needed here? Note that if you move out
struct C so that it isn't a member of A anymore, clang correctly
says that I need the template keyword. g++ wants the keyword
in both cases:

$ g++-4.9 -std=c++11 -fsyntax-only templatebase.cpp 
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
 struct A<T>::C : public A<T>::B<int> {
                                    ^
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
 struct A<T>::C : public A<T>::B<int> {
                               ^
templatebase.cpp:12:38: error: expected class-name before '{' token
 struct A<T>::C : public A<T>::B<int> {
                                      ^
3) tupleconstructor.cpp
#include <tuple>

std::tuple<int, int, int>
func() {
   return { 0, 1, 2 };
}

I don't know how to phrase the situation in standardese terms (is it list-initialization?).
It seems to me that clang picks the forwarding constructor, g++ the explicit initializer-list constructor.

$ g++-4.9 -std=c++11 -fsyntax-only tupleconstructor.cpp 
tupleconstructor.cpp: In function 'std::tuple<int, int, int> func()':
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}]'
    return { 0, 1, 2 };
                     ^

In all these three cases, who is right? Are these bugs in clang?
In this case, should I make a separate bug report for each case, right? I've attached the single test cases

Greetings,
Nicola


-------------- next part --------------
A non-text attachment was scrubbed...
Name: templatebase.cpp
Type: application/octet-stream
Size: 192 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20140810/78046690/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: transitive-friend.cpp
Type: application/octet-stream
Size: 107 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20140810/78046690/attachment-0001.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: tupleconstructor.cpp
Type: application/octet-stream
Size: 78 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20140810/78046690/attachment-0002.obj>
-------------- next part --------------




More information about the cfe-dev mailing list