[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