C++11 with gcc 4.6.1 on a mac - c++

I'm new to the mac and trying to get gcc 4.6 working.
I installed MacPorts and installed gcc 4.6.1 (by executing sudo port install gcc46). I'm trying to compile a simple test code that compiles fine on Linux (with gcc 4.6.1 and 4.6.2) and Windows, but I'm getting errors that make me thing there is something wrong with the installed libraries.
#include <iostream>
#include <type_traits>
#include <future>
struct test {
void get() {}
};
/*template<typename Func>
test async(const Func &f) {
f();
return test();
}*/
using namespace std;
int main (int argc, const char * argv[])
{
auto t1 = async([]() -> int{
cout << "This is thread 1" << endl;
return 1;
});
auto t2 = async([]() -> int {
cout << "This is thread 2" << endl;
return 2;
});
std::cout << "This is the main thread" << endl;
t1.get();
t2.get();
return 0;
}
The error messages:
macbook01:Test fozi$ g++ main.cpp -o test -std=c++0x
main.cpp: In function 'int main(int, const char**)':
main.cpp:30:6: error: invalid use of incomplete type 'std::enable_if<true, std::future<int> >::type'
/opt/local/include/gcc46/c++/future:111:11: error: declaration of 'std::enable_if<true, std::future<int> >::type'
main.cpp:30:6: error: unable to deduce 'auto' from '<expression error>'
main.cpp:35:6: error: invalid use of incomplete type 'std::enable_if<true, std::future<int> >::type'
/opt/local/include/gcc46/c++/future:111:11: error: declaration of 'std::enable_if<true, std::future<int> >::type'
main.cpp:35:6: error: unable to deduce 'auto' from '<expression error>'
/opt/local/include/gcc46/c++/future: At global scope:
/opt/local/include/gcc46/c++/future:150:5: error: 'typename std::enable_if<(! std::is_same<typename std::decay<_Functor>::type, std::launch>::value), std::future<decltype (declval<_Fn>()((declval<_Args>)()...))> >::type std::async(_Fn&&, _Args&& ...) [with _Fn = main(int, const char**)::<lambda()>, _Args = {}, typename std::enable_if<(! std::is_same<typename std::decay<_Functor>::type, std::launch>::value), std::future<decltype (declval<_Fn>()((declval<_Args>)()...))> >::type = std::future<int>]', declared using local type 'main(int, const char**)::<lambda()>', is used but never defined [-fpermissive]
/opt/local/include/gcc46/c++/future:150:5: error: 'typename std::enable_if<(! std::is_same<typename std::decay<_Functor>::type, std::launch>::value), std::future<decltype (declval<_Fn>()((declval<_Args>)()...))> >::type std::async(_Fn&&, _Args&& ...) [with _Fn = main(int, const char**)::<lambda()>, _Args = {}, typename std::enable_if<(! std::is_same<typename std::decay<_Functor>::type, std::launch>::value), std::future<decltype (declval<_Fn>()((declval<_Args>)()...))> >::type = std::future<int>]', declared using local type 'main(int, const char**)::<lambda()>', is used but never defined [-fpermissive]
Note that if I use my dummy async function it compiles and runs fine.
I'm kind of stuck, do I have to install a specific library (version)? How do I do that?

I've had similar issues with gcc-4.6.1 and OS X 10.6. The problem is C++0x's thread is not supported at the moment on OS X.
See this post: c++0x, std::thread error (thread not member of std)
If you look in "${prefix}/include/c++/4.6.1/future" header file, you'll see the line:
#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) \
&& defined(_GLIBCXX_ATOMIC_BUILTINS_4)
Unfortunately, _GLIBCXX_HAS_GTHREADS evalute to 0 on OS X.

We're getting there
gcc 4.7 (port) compiles this code just fine.
Xcode 4.3 comes with clang 3.1 which is supposed to support this, but it crashes when I try to compile. However I built clang from SVN and replaced the compiler Xcode is using and now it compiles and runs fine as well.
And it only took half a year.

Try g++ -v to get the version of G++ you're using. I'm not using a pre-compiled compiler but perhaps it is the same for you.
The GCC 4.6.0 is installed in /usr/local/bin under the name x86_64-apple-darwin10.7.0-g++
If you still use the simple g++ command, it may still be /usr/bin/g++, which is Apple's llvm-gcc flavor.

Related

Why am i getting a "In instantiation of ‘struct std::_Bind_simple<Fctor()>’ " error

I'm just getting started with multi-threading in C++ 11 and I stumbled upon an error that I do not understand.
This is my multi1.cpp file:
#include <iostream>
#include <thread>
using namespace std;
class Fctor {
public:
void operator() (string msg) {
std :: cout << "From Fctor: "<< msg << std :: endl;
}
};
int main()
{
string s = "Hello world";
std::thread t1((Fctor()),s);
t1.join();
return 0;
}
Now I try to run this file in a cygwin environment using the following command:
$ g++ -std=c++11 multi1.cpp -o output
This leads to an error in compilation that prints:
In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.9.3/include/c++/thread:39:0,
from multi1.cpp:2:
/usr/lib/gcc/x86_64-pc-cygwin/4.9.3/include/c++/functional: In instantiation of ‘struct std::_Bind_simple<Fctor()>’:
/usr/lib/gcc/x86_64-pc-cygwin/4.9.3/include/c++/thread:137:47: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = Fctor&; _Args = {}]’
multi1.cpp:15:19: required from here
/usr/lib/gcc/x86_64-pc-cygwin/4.9.3/include/c++/functional:1665:61: error: no type named ‘type’ in ‘class std::result_of<Fctor()>’
typedef typename result_of<_Callable(_Args...)>::type result_type;
^
/usr/lib/gcc/x86_64-pc-cygwin/4.9.3/include/c++/functional:1695:9: error: no type named ‘type’ in ‘class std::result_of<Fctor()>’
_M_invoke(_Index_tuple<_Indices...>)
I cannot comprehend what the compiler is trying to tell me. I am trying to understand how things work while I go through the C++ multithreading tutorial on YouTube by Bo Qian.
Thanks in advance guys.

How to wrap a call to `std::thread` constructor? (that works with gcc, VS and icpc)

Original Post (with errors)
I want to wrap a call to std::thread constructor (to keep track of all threads running so I can join them or do other things). In this example, the t1 thread gets constructed properly, but the t2 thread doesn't using gcc 4.8.1. However, on Windows (VS2012) it compiles without error and runs without error. Based on the discussion here, this may appear to be a bug in gcc, but arguably it is actually a bug in VS. What is the correct way of doing this?
#include <iostream>
#include <thread>
class A {
public:
void foo(int n ) { std::cout << n << std::endl; }
};
template<class F, class Arg>
std::thread& wrapper(F&& f, Arg&& a)
{
std::thread* t = new std::thread(f,a,100);
return *t;
}
int main()
{
A a;
std::thread t1(&A::foo, &a, 100);
t1.join();
std::thread t2 = wrapper(&A::foo, &a);
t2.join();
return 0;
}
Here is the compiler error
-bash-4.1$ make
g++ -std=c++11 main.cpp -o main
main.cpp: In function ‘int main()’:
main.cpp:23:41: error: use of deleted function ‘std::thread::thread(std::thread&)’
std::thread t2 = wrapper(&A::foo, &a);
^
In file included from main.cpp:2:0:
/opt/rh/devtoolset-2/root/usr/include/c++/4.8.1/thread:125:5: error: declared here
thread(thread&) = delete;
^
make: *** [all] Error 1
Update
I asked the wrong question here and am about to delete it, but because the answers are helpful, I will leave it. The problem was that the Intel icpc 14.0 compiler (not gcc 4.8.1) was throwing the same error regarding bind as discussed here. And it has nothing to do with the "wrapper" but just calling std::thread with a member function instead of static function.
The complaints about the memory leak are 100% valid, but that was me making an unfortunate simplification to the example (from my real code). The actual code saves the threads in a container and deletes the threads on destruction.
Here is a better example:
#include <iostream>
#include <thread>
class A {
public:
void foo() { }
template<class Function, class Arg>
std::thread* wrapper(Function&& f, Arg&& a)
{
auto t = new std::thread(f,a);
return t;
}
};
int main()
{
A a;
std::thread t1(&A::foo, &a);
t1.join();
std::thread* t2 = a.wrapper(&A::foo, &a);
t2->join();
delete t2;
return 0;
}
And the output for g++ (4.8.1) which works
-bash-4.1$ make CXX=g++
g++ -lpthread -std=c++11 main.cpp -o main
and the output for the Intel compiler icpc (14.0) which doesn't work
-bash-4.1$ make CXX=icpc
icpc -lpthread -std=c++11 main.cpp -o main
/opt/rh/devtoolset-2/root/usr/include/c++/4.8.1/functional(1697): error: class "std::result_of<std::_Mem_fn<void (A::*)()> (A *)>" has no member "type"
typedef typename result_of<_Callable(_Args...)>::type result_type;
^
detected during:
instantiation of class "std::_Bind_simple<_Callable (_Args...)> [with _Callable=std::_Mem_fn<void (A::*)()>, _Args=<A *>]" at line 1753
instantiation of "std::_Bind_simple_helper<_Callable, _Args...>::__type std::__bind_simple(_Callable &&, _Args &&...) [with _Callable=void (A::*)(), _Args=<A *>]" at line 137 of "/opt/rh/devtoolset-2/root/usr/include/c++/4.8.1/thread"
instantiation of "std::thread::thread(_Callable &&, _Args &&...) [with _Callable=void (A::*)(), _Args=<A *>]" at line 20 of "main.cpp"
/opt/rh/devtoolset-2/root/usr/include/c++/4.8.1/functional(1726): error: class "std::result_of<std::_Mem_fn<void (A::*)()> (A *)>" has no member "type"
typename result_of<_Callable(_Args...)>::type
^
detected during:
instantiation of class "std::_Bind_simple<_Callable (_Args...)> [with _Callable=std::_Mem_fn<void (A::*)()>, _Args=<A *>]" at line 1753
instantiation of "std::_Bind_simple_helper<_Callable, _Args...>::__type std::__bind_simple(_Callable &&, _Args &&...) [with _Callable=void (A::*)(), _Args=<A *>]" at line 137 of "/opt/rh/devtoolset-2/root/usr/include/c++/4.8.1/thread"
instantiation of "std::thread::thread(_Callable &&, _Args &&...) [with _Callable=void (A::*)(), _Args=<A *>]" at line 20 of "main.cpp"
compilation aborted for main.cpp (code 2)
make: *** [all] Error 2
-bash-4.1$
Your wrapper should be like this:
template<class F, class Arg>
std::thread wrapper(F&& f, Arg&& a)
{
return std::thread(std::forward<F>(f), std::forward<Arg>(a));
}
std::thread is not copyable. Given that wrapper returns a std::thread&, wrapper(&A::foo, &a); is an lvalue, and thus the initialisation of t2 requires a copy. That's what the compiler error is about.
Sadly, some versions of Visual Studio will happily perform a move here, even though there are no rvalues involved.
Something like std::thread* t = new std::thread(f,a,100); return *t; is pretty much the same as return *new std::thread(f,a,100);, and that clearly shows the memory leak operator: *new. Don't do this.
While not copyable, std::thread is movable. You just have to make it so that wrapper(&A::foo, &a); is an rvalue. That can be done simply by writing the function in the most natural style, like so:
template<class F, class Arg>
std::thread wrapper(F&& f, Arg&& a)
{
return std::thread(f, a, 100);
}
This however fails to correctly forward the arguments preserving their value category (as is, it turns rvalues into lvalues), even though it's not a problem for this particular example. In order to have general applicability, the function body should forward the arguments properly, like so: return std::thread(std::forward<F>(f), std::forward<Arg>(a), 100);.

Odd behavior with std::async

Consider the following sample code:
#include <future>
#include <array>
#include <cassert>
typedef std::array<int, 5> foo_t;
foo_t* bar(foo_t& foo) {
return &foo;
}
int main() {
foo_t foo;
auto a = std::async(bar, foo);
auto b = std::async(bar, foo);
assert(a.get() == b.get());
return 0;
}
GCC 4.6.3 compiles this with no complaints. However, this fails at runtime with:
test: test.cpp:15: int main(): Assertion `a.get() == b.get()' failed.
Aborted (core dumped)
GCC 4.8.2, however, refuses to compile the file:
In file included from /usr/local/include/c++/4.8.2/future:38:0,
from test.cpp:1:
/usr/local/include/c++/4.8.2/functional: In instantiation of 'struct std::_Bind_simple<std::array<int, 5ul>* (*(std::array<int, 5ul>))(std::array<int, 5ul>&)>':
/usr/local/include/c++/4.8.2/future:1525:70: required from 'std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(std::launch, _Fn&&, _Args&& ...) [with _Fn = std::array<int, 5ul>* (&)(std::array<int, 5ul>&); _Args = {std::array<int, 5ul>&}; typename std::result_of<_Functor(_ArgTypes ...)>::type = std::array<int, 5ul>*]'
/usr/local/include/c++/4.8.2/future:1541:36: required from 'std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(_Fn&&, _Args&& ...) [with _Fn = std::array<int, 5ul>* (&)(std::array<int, 5ul>&); _Args = {std::array<int, 5ul>&}; typename std::result_of<_Functor(_ArgTypes ...)>::type = std::array<int, 5ul>*]'
test.cpp:13:30: required from here
/usr/local/include/c++/4.8.2/functional:1697:61: error: no type named 'type' in 'class std::result_of<std::array<int, 5ul>* (*(std::array<int, 5ul>))(std::array<int, 5ul>&)>'
typedef typename result_of<_Callable(_Args...)>::type result_type;
^
/usr/local/include/c++/4.8.2/functional:1727:9: error: no type named 'type' in 'class std::result_of<std::array<int, 5ul>* (*(std::array<int, 5ul>))(std::array<int, 5ul>&)>'
_M_invoke(_Index_tuple<_Indices...>)
^
This appears to be a libstdc++ issue.
So my questions are:
1 - should GCC reject this code, or is there something in the standard that I am not aware of.
2 - should the assertion fail? The expected behavior is that async functions that take the same reference should refer to the same object, but it appears that a copy is made local to the async task.
I've tried compiling with clang, but it has the same compile error issues (as it shares the same libstdc++) with 4.8.2, and it can't compile the 4.6.3 library headers.
Yes, gcc should reject this code. std::async copies the arguments and forwards them as rvalues. You cannot bind an rvalue to an lvalue reference, so this fails. If you want to pass by reference use std::ref(foo). In this specific example, the call to std::async(bar,foo) essentially does the following:
template<typename F>
future<foo_t*> async(F& func,foo_t& arg){
F func_copy(func);
foo_t arg_copy(arg);
// on background thread
internal_set_future_result(func_copy(std::move(arg_copy)));
return ...;
}
If you use std::ref(foo) then the assertion should not fail. If the code doesn't compile then it's a moot point.

Compilation error on using boost::future .then()

I am trying to use boost::future .then() functionality.
The snippet is taken from Boost 1.54.0 thread synchronisation documentation
#include <string>
#include <boost/thread/future.hpp>
int main() {
boost::future<int> f1 = boost::async([]() { return 123; });
boost::future<std::string> f2 = f1.then([](boost::future<int> f)->std::string {
int x = f.get();
return ("Done" + std::to_string(x));
});
}
Setup :
Ubuntu 13.04
g++ version g++ (Ubuntu 4.8.1-2ubuntu1~13.04) 4.8.1
Boost version 1.54.0
command line :
g++ then_test.cc -std=c++0x -DBOOST_THREAD_VERSION=4 -I /home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost -L /home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/stage/lib -static -lboost_thread-mt -lboost_date_time-mt -lboost_system-mt -lpthread
Error:
g++ then_test.cc -std=c++0x -DBOOST_THREAD_VERSION=4 -I /home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost -L /home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/stage/lib -static -lboost_thread-mt -lboost_date_time-mt -lboost_system-mt -lpthread
then_test.cc: In function ‘int main()’:
then_test.cc:10:44: error: no matching function for call to ‘boost::future<int>::then(main()::__lambda1)’
});
^
then_test.cc:10:44: note: candidates are:
In file included from then_test.cc:2:0:
/home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/boost/thread/future.hpp:1598:9: note: template<class F> boost::future<typename boost::result_of<F(boost::future<R>&)>::type> boost::future<R>::then(F&&) [with F = F; R = int]
then(BOOST_THREAD_FWD_REF(F) func);
^
/home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/boost/thread/future.hpp:1598:9: note: template argument deduction/substitution failed:
In file included from then_test.cc:2:0:
/home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/boost/thread/future.hpp: In substitution of ‘template<class F> boost::future<typename boost::result_of<F(boost::future<R>&)>::type> boost::future<R>::then(F&&) [with F = F; R = int] [with F = main()::__lambda1]’:
then_test.cc:10:44: required from here
/home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/boost/thread/future.hpp:62:29: error: no type named ‘type’ in ‘struct boost::result_of<main()::__lambda1(boost::future<int>&)>’
#define BOOST_THREAD_FUTURE future
^
/home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/boost/thread/future.hpp:3840:3: note: in expansion of macro ‘BOOST_THREAD_FUTURE’
BOOST_THREAD_FUTURE<R>::then(BOOST_THREAD_FWD_REF(F) func)
^
In file included from then_test.cc:2:0:
/home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/boost/thread/future.hpp:1601:9: note: template<class F> boost::future<typename boost::result_of<F(boost::future<R>&)>::type> boost::future<R>::then(boost::launch, F&&) [with F = F; R = int]
then(launch policy, BOOST_THREAD_FWD_REF(F) func);
^
/home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/boost/thread/future.hpp:1601:9: note: template argument deduction/substitution failed:
then_test.cc:10:44: note: cannot convert ‘<lambda closure object>main()::__lambda1{}’ (type ‘main()::__lambda1’) to type ‘boost::launch’
});
Please let me know if I am missing something here.
Passing future by reference to .then() fixes the compilation issue on gcc 4.8 & clang.
For windows and gcc 4.7 we additionally need to define BOOST_RESULT_OF_USE_DECLTYPE. (as per Xeo's comment). For gcc 4.8 & clang it seems available already.
boost::future<std::string> f2 = f1.then([](boost::future<int>& f)->std::string {
^

GCC 4.8 is reversing variadic template parameter pack

I just upgraded to GCC 4.8 and some variadic template code no longer compiles correctly. I've created a minimal example below:
#include <tuple>
#include <iostream>
template <class T, class ... OtherT>
void something( std::tuple<T, OtherT...> & tup )
{
std::cout << std::get<1>(tup) << std::endl;
}
int main()
{
std::tuple<int, char, bool> myTuple(3, 'a', true);
// Compiles OK in GCC 4.6.3 but NOT 4.8
something<int, char, bool>( myTuple );
// Compiles OK in GCC 4.8 but NOT 4.6.3
something<int, bool, char>( myTuple );
return 0;
}
The output of this will be (if commenting out the incorrect version for GCC 4.6.3/4.8)
'a'.
The error produced by GCC 4.6.3 is:
./test.cpp: In function ‘int main()’:
./test.cpp:18:39: error: no matching function for call to ‘something(std::tuple<int, char, bool>&)’
./test.cpp:18:39: note: candidate is:
./test.cpp:5:6: note: template<class T, class ... OtherT> void something(std::tuple<_Head, _Tail ...>&)
The error produced by GCC 4.8 is:
./test.cpp: In function ‘int main()’:
./test.cpp:15:39: error: no matching function for call to ‘something(std::tuple<int, char, bool>&)’
something<int, char, bool>( myTuple );
^
./test.cpp:15:39: note: candidate is:
./test.cpp:5:6: note: template<class T, class ... OtherT> void something(std::tuple<_El0, _El ...>&)
void something( std::tuple<T, OtherT...> & tup )
^
./test.cpp:5:6: note: template argument deduction/substitution failed:
./test.cpp:15:39: note: mismatched types ‘bool’ and ‘char’
something<int, char, bool>( myTuple );
It seems like in GCC 4.8, variadic template types are reversed when expanded, though oddly enough they don't "really" get reversed as proved by the output - it will be 'a' regardless of the ordering. Clang 3.3 agrees with the GCC 4.6.3 output.
Is this a bug in GCC 4.8 or something else?
EDIT: added a bug report to GCC here: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56774
This looks like a bug to me, GCC 4.8.0 and GCC 4.7.2 seem to be affected. Clang 3.2 and GCC 4.6.3 agree that the first call to something is the correct one and I really fail to see how GCC 4.7.2+ can consider the second call to be acceptable.
I'd say: Report a bug against GCC.
Update: I added a minimalistic example to the GCC bug report, just to help them and prove that it's a pure compiler bug and has nothing to do with std::tuple. Here's the reduced code:
template< typename... > struct X {};
template< typename T, typename... Ts >
void f( X< T, Ts... >& ) {}
int main()
{
X< int, bool, char > t;
f< int, char, bool >(t);
}
Update 2: It's now fixed for GCC 4.7.3, GCC 4.8.1 and GCC 4.9 - kudos to the GCC team for an insanely fast fix!