I`am trying to compile code bellow. GCC compile it, but clang not.
Error: no member named 'sa' in 'A' static void sf() {A::sa('j');}
What's problem?
test.cpp:
template<typename T>
class A
{
private:
public:
void f() {this->a('j');}
static void sf() {A::sa('j');}
#ifdef U
void a(char x) {}
static void sa(char x) {}
#endif
};
UPD:
I use compilers, that included in Android NDK r10c
gcc 4.9:
cd C:\Tools\android-ndk-r10c\toolchains\x86-4.9\prebuilt\windows-x86_64\bin
clang++.exe -c C:\Users\Barkov_V\Desktop\test.cpp
clang 3.5:
cd C:\Tools\android-ndk-r10c\toolchains\llvm-3.5\prebuilt\windows-x86_64\bin
i686-linux-android-gcc-4.9.exe -c C:\Users\Barkov_V\Desktop\test.cpp
Related
Given this code:
template <typename>
struct Check { constexpr static bool value = true; };
struct A {
A() noexcept(Check<int>::value) = default;
};
Compiling with various versions of GNU g++ works fine, but it always fails with clang++ 5.0.1 (both with libstdc++ and libc++):
$ g++-4.9.4 test.cpp -c -o test -std=c++11 -Wall -Wextra
$ g++-5.4.0 test.cpp -c -o test -std=c++11 -Wall -Wextra
$ g++-6.4.0 test.cpp -c -o test -std=c++11 -Wall -Wextra
$ g++-7.2.0 test.cpp -c -o test -std=c++11 -Wall -Wextra
$ clang++ test.cpp -c -o test -std=c++11 -Wall -Wextra -Weverything
test.cpp:2:16: warning: 'constexpr' specifier is incompatible with C++98 [-Wc++98-compat]
struct Check { constexpr static bool value = true; };
^
test.cpp:5:39: warning: defaulted function definitions are incompatible with C++98 [-Wc++98-compat]
A() noexcept(Check<int>::value) = default;
^
test.cpp:5:9: warning: noexcept specifications are incompatible with C++98 [-Wc++98-compat]
A() noexcept(Check<int>::value) = default;
^
test.cpp:5:5: error: exception specification is not available until end of class definition
A() noexcept(Check<int>::value) = default;
^
test.cpp:5:18: note: in instantiation of template class 'Check<int>' requested here
A() noexcept(Check<int>::value) = default;
^
3 warnings and 1 error generated.
$ clang++ test.cpp -c -o test -std=c++11 -Wall -Wextra
test.cpp:5:5: error: exception specification is not available until end of class definition
A() noexcept(Check<int>::value) = default;
^
test.cpp:5:18: note: in instantiation of template class 'Check<int>' requested here
A() noexcept(Check<int>::value) = default;
^
1 error generated.
On Compiler Explorer this also seems to work for all versions of GCC newer 4.7.0 (including trunk), but fails for all Clang versions except for Clang 3.4.0, 3.5.0, 3.5.1 and trunk. So this seems like Clang bug.
Is it possible to work around this bug? How? Is this bug already tracked somewhere?
EDIT:
I tracked this bug down to Clang PR23383. As of now there is no notice about this being fixed in Clang although it seems to work with Clang trunk in Compiler Explorer.
This might be related to PR30860 (and C++ DR1330 as described in Richard Smith's comment on PR30860). It seems that the issue has something to do about when the contents of the noexcept() are parsed.
And so it turns out that one obvious workaround is to try to force the compiler to parse these contents elsewhere. One possible solution would be to provide the contents noexcept() as a constexpr member constant:
template <typename>
struct Check { constexpr static bool value = true; };
struct A {
A() noexcept(workaround) = default;
private: /* Work around Clang PR23383: */
static constexpr bool workaround = Check<int>::value;
};
Unfortunately, this does not work in all cases, e.g. such as this:
#include <type_traits>
struct Base { virtual ~Base() noexcept; };
struct OuterClass {
class InnerDerived: public Base {
private:
static constexpr auto const workaround =
std::is_nothrow_default_constructible<Base>::value;
public:
InnerDerived() noexcept(workaround);
};
class InnerDerived2: public InnerDerived {
private:
static constexpr auto const workaround2 =
std::is_nothrow_default_constructible<InnerDerived>::value;
public:
InnerDerived2() noexcept(workaround2);
};
};
The latter yields the error even when using Clang trunk in Compiler Explorer. Any ideas why?
Given the following code as test.cpp,
Building using clang++ -c test.cpp -o test.o -g; clang++ test.o -g -all_load, setting breakpoint at return a.getValue(); and attempting to p a.getValue() from lldb:
Running llvm 3.8.0 on unix - works perfectly
Running xcode or llvm 8.1.0 on OSX - I get the following error:
error: Couldn't lookup symbols:
__ZNK4Test7MyClassILi2ELi3EE8getValueEv
Two interesting facts:
If I remove the last template argument - all works well
If I build directly without going through the .o file (clang++ test.cpp) = all goes well
Anyone has a clue what is going on, and how can it be fixed?
namespace Test{
template<class T>
class BLA{
public:
T getBlaValue() const{return 3;}
};
template <int N1, int N2, template<class T>class Impl = BLA>
class MyClass {
private:
public:
__attribute__((used))
int getValue() const
{
return 3;
}
};
}
int main()
{
Test::MyClass<2, 3> a;
return a.getValue();
}
I'm trying to implement the move constructor outside the class body, but it won't compile correctly
#include <boost/move/move.hpp>
class Test
{
BOOST_COPYABLE_AND_MOVABLE(Test)
public:
Test() {}
Test(const Test & other) { }
Test(BOOST_RV_REF(Test) other);
Test & operator=(BOOST_COPY_ASSIGN_REF(Test) other) { return *this; }
Test & operator=(BOOST_RV_REF(Test) other) { return *this; }
};
Test::Test(BOOST_RV_REF(Test) other) { }
I compiled this code with g++, my g++ version is 4.4.7
$ g++ -c test.cpp
test.cpp:15: error: prototype for 'Test::Test(boost::rv<Test>&)' does not match any in class 'Test'
test.cpp:9: error: candidates are: Test::Test(boost:rv<Test>&)
test.cpp:8: error: Test::Test(const Test&)
test.cpp:7: error: Test::Test()
It also failed with g++ 5.4.0 – flyzero
Must be your boost version.
It works fine with g++ 5.4.1 and Boost 1.64. If not, check the preprocessor output for any include/macro mishaps.
In Linux, ::boost::rv is declared with may_alias attribute. My code compile correctly after removing the may_alias attribute.
#define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS __attribute__((__may_alias__))
template <class T>
class rv
: public ::boost::move_detail::if_c
< ::boost::move_detail::is_class<T>::value
, T
, ::boost::move_detail::nat
>::type
{
rv();
~rv() throw();
rv(rv const&);
void operator=(rv const&);
} BOOST_MOVE_ATTRIBUTE_MAY_ALIAS;
I have the following code:
#include <iostream>
#include <memory>
using namespace std;
class A
{
public:
void foo() const;
};
void A::foo() const {}
std::unique_ptr<A> foo2()
{
std::unique_ptr<A> pa(new A());
return pa;
}
void
foo()
{
const A& ra = *foo2();
ra.foo();
}
int
main()
{
foo();
return 0;
}
I am trying to use clang's scan-build:
scan-build g++ --std=c++11 unique_ptr.cpp
This program compiles and runs fine with g++.
I am using CentOS and clang3.8 and g++4.8.5.
Error Message:
error: no type named 'unique_ptr' in namespace 'std'
std::unique_ptr<A> foo2()
~~~~~^
You should use:
scan-build g++ -std=c++11 unique_ptr.cpp
Instead of:
scan-build g++ --std=c++11 unique_ptr.cpp
-std works (while --std doesn't) because scan-build checks specifically for the -std flag.
In clang/tools/scan-build/libexec/ccc-analyzer:
if ($Arg =~ /^-std=/) {
push #CompileOpts,$Arg;
next;
}
I have a function that is declared like:
template<typename T>
void MyFunction();
And a class:
template<typename T>
class MyClass
{
public:
typedef void (*Function_T)();
Function_T m_Func;
void DoSomething()
{
m_Func = &MyFunction<T>;
}
}
When I use the class, I undefined symbols error on MyFunction<T>.
If I change DoSomething to
void DoSomething()
{
m_Func = &MyFunction<T>;
return;
MyFunction<T>();
}
Everything works, but that looks like a workaround and will probably not work with optimization.
I cannot add
template void MyFunction<T>;
to the class because it says it cannot be in class. Is there any other way I can force instantiation of the function?
Edit:
I was able to write a test that fails, but in g++ it has a different message and actually a compiler error: http://ideone.com/RbMnh
Your code will work with optimization as well. Although, I don't know why simply m_Func = &MyFunction<T> doesn't work. GCC 4.3.4 compiles it fine. Which compiler you're using?
And you can also do this:
void DoSomething()
{
if ( false) MyFunction<T>();
m_Func = &MyFunction<T>;
return;
}
By the way, the function pointer type is incorrectly defined. It should be this:
typedef void (*Function_T)();
// ^^ put this!
Your code compiles fine for me using GCC, so I'm not sure if this solution solves your particular problem, but you can explicitly instantiate template functions like so:
// Template function defined:
template <typename T>
void MyFunction() {
// body
}
// Template function instantiated:
template void MyFunction<int>();
The issue can be either a compiler bug, or an error in the parts of the code that you are not showing. Try to build a minimal example that reproduces the problem, this is the minimal example that I have been able to produce, and compiles fine with both clang++ 2.8 and g++ 4.4/4.5:
drodriguez#drodriguez-desktop:/tmp$ cat test.cpp
#include <iostream>
template <typename T>
void function() {
}
template <typename T>
struct type {
typedef void (*Func)();
Func _f;
void f() {
_f = &function<T>;
}
};
int main() {
type<int> t;
t.f();
std::cout << t._f << std::endl;
}
drodriguez#drodriguez-desktop:/tmp$ /usr/bin/clang++ --version
clang version 2.8 (branches/release_28)
Target: x86_64-pc-linux-gnu
Thread model: posix
drodriguez#drodriguez-desktop:/tmp$ /usr/bin/clang++ -o test test.cpp && ./test
1
drodriguez#drodriguez-desktop:/tmp$ g++ --version
g++ (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
drodriguez#drodriguez-desktop:/tmp$ g++-4.4 -o test test.cpp && ./test
1