Threads in c++, cannot use parameters - c++

I am trying to start a thread t:
#include <iostream>
#include <fstream>
#include <string>
#include <thread>
void function(int p1, int p2, int p3){
std::cout<<p1<<p2<<p3<<std::endl;
}
int main(int argc, char const *argv[]) {
std::cout<<"starting"<<std::endl;
std::thread t(function, 1, 2, 3);
std::cout<<"created thread"<<std::endl;
t.join();
std::cout<<"end"<<std::endl;
return 0;
}
My compiler tells me this:
doesntwork.cpp:12:15: error: no matching constructor for
initialization of 'std::thread'
std::thread t(function, 1, 2, 3);
^ ~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:408:9: note:
candidate constructor template not viable: requires single
argument '__f', but 4 arguments were provided
thread::thread(_Fp __f)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:289:5: note:
candidate constructor not viable: requires 1 argument, but 4
were provided
thread(const thread&);
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:296:5: note:
candidate constructor not viable: requires 0 arguments, but
4 were provided
thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
^
1 error generated.
In the first case it tells me that for the thread t, there is no constructor that can use more than 1 parameter, while if I just remove the arguments (p1, p2, p3) it doesn't work either because I am not passing any argmuent....
Compiler information:
Configured with: --prefix=/Library/Developer/CommandLineTools/usr
--with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 10.0.0 (clang-1000.10.44.2)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
built command used: g++ doesntwork.cpp -o doesntwork.out
Is there something different you have to do when compiling with threads? Am I missing something very obvious?

On macOS, g++ (from Xcode: Version 10.0 (10A255)) is aliased to clang which by default does not work with c++11 threads. To solve the problem you have to use the -std=c++11 switch.
Example:
g++ -std=c++11 fileToCompile.cpp -o outputFile.out
This should let you compile c++ code using c++11 threads.
Thank you to #M.M for providing the answer above in the comments.

Related

Why can't I compile this simple thread test?

I wanted to test some things with threads on my Macbook pro, but I can't get it to work.
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/c++/4.2.1
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.2.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
this is the Version of clang installed on my machine. I tried to code some vector of threads but that didn't work so I went back and copied an example from SO.
#include <string>
#include <iostream>
#include <thread>
using namespace std;
// The function we want to execute on the new thread.
void task1(string msg)
{
cout << "task1 says: " << msg;
}
int main()
{
// Constructs the new thread and runs it. Does not block execution.
thread t1(task1, "Hello");
// Do other things...
// Makes the main thread wait for the new thread to finish execution, therefore blocks its own execution.
t1.join();
}
But I am getting a compiler error..
error: no matching constructor for initialization of
'std::__1::thread'
thread t1(task1, "Hello");
I guess my machine is the problem, but why?
Somehow, you built your code as C++03, probably by not providing a standard revision flag explicitly. libc++, the LLVM implementation of the standard library allows using <thread> in C++03 code. The source has conditional compilation of the following sort:
#ifndef _LIBCPP_CXX03_LANG
template <class _Fp, class ..._Args,
class = typename enable_if
<
!is_same<typename __uncvref<_Fp>::type, thread>::value
>::type
>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
explicit thread(_Fp&& __f, _Args&&... __args);
#else // _LIBCPP_CXX03_LANG
template <class _Fp>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
explicit thread(_Fp __f);
#endif
In C++11 and higher, the constructor adheres to the C++11 standard. Otherwise, it accepts only a callable without additional arguments. I managed to reproduce your error by providing the C++03 standard revision flag. The error even mentions this candidate:
prog.cc:16:12: error: no matching constructor for initialization of 'std::__1::thread'
thread t1(task1, "Hello");
^ ~~~~~~~~~~~~~~
/opt/wandbox/clang-8.0.0/include/c++/v1/thread:408:9: note: candidate constructor template not viable: requires single argument '__f', but 2 arguments were provided
thread::thread(_Fp __f)

multithreading c++ passing arguments to a function

I have been trying to pass arguments to a thread function but haven't been able to. I tried reading about it (Passing multiple arguments to a threaded function) but I still couldn't figure it out. Here is my code:
#include <iostream>
#include <thread>
using namespace std;
void func(int t)
{
cout << t << endl;
}
int main()
{
thread t1(func,4);
t1.join();
return 0;
}
I ran it in the command line (I use zsh incase that matters) by doing this:
g++ test.cpp
./a.out
but I got these errors:
thread_test.cpp:14:12: error: no matching constructor for initialization of 'std::__1::thread'
thread t1(func,4);
^ ~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:379:9: note: candidate constructor template not viable: requires single argument '__f', but
2 arguments were provided
thread::thread(_Fp __f)
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:268:5: note: candidate constructor not viable: requires 1 argument, but 2 were provided
thread(const thread&);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:275:5: note: candidate constructor not viable: requires 0 arguments, but 2 were provided
thread() _NOEXCEPT : __t_(0) {}
^
1 error generated.
in case this is important I am using a mac with OSX 10.11.4
Also, to see what versions of c++ I was compiling with I ran this command and got this out put:
g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/c++/4.2.1
Apple LLVM version 7.3.0 (clang-703.0.31)
Target: x86_64-apple-darwin15.4.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
Pass -std=c++11 and it will work; see my transcript below. (Running on OS X.)
nathanst% g++ t.cpp
t.cpp:13:12: error: no matching constructor for initialization of 'std::__1::thread'
thread t1(func,4);
^ ~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:379:9: note: candidate constructor template not viable: requires single argument '__f', but 2 arguments were
provided
thread::thread(_Fp __f)
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:268:5: note: candidate constructor not viable: requires 1 argument, but 2 were provided
thread(const thread&);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:275:5: note: candidate constructor not viable: requires 0 arguments, but 2 were provided
thread() _NOEXCEPT : __t_(0) {}
^
1 error generated.
nathanst% g++ -std=c++11 t.cpp

Thread in C++ in MacOS X

I'm trying to run some code using threads in standard C++ (installed with XCode) in MacOS X Mavericks. But I'm getting some errors. Here's a minimal working example:
#include <thread>
#include <iostream>
void run (int x) {
std::cout<<".";
}
int main (int argc, char const *argv[])
{
std::thread t(run);
}
The error I'm getting:
minimal.cpp:10:17: error: no matching constructor for initialization of 'std::thread'
std::thread t(run,0);
^ ~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/thread:372:9: note: candidate constructor template not viable: requires single argument '__f', but 2 arguments
were provided
thread::thread(_Fp __f)
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/thread:261:5: note: candidate constructor not viable: requires 1 argument, but 2 were provided
thread(const thread&);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/thread:268:5: note: candidate constructor not viable: requires 0 arguments, but 2 were provided
thread() _NOEXCEPT : __t_(0) {}
^
1 error generated.
I've been able to track the problem to my compiler defining _LIBCPP_HAS_NO_VARIADICS, which is defined because of
#if !(__has_feature(cxx_variadic_templates))
#define _LIBCPP_HAS_NO_VARIADICS
#endif
Any help would be appreciated.
Thank you!
Thanks to pwny and PeterT, I figured out the error.
I just needed to compile with clang++ -std=c++11 minimal.cpp and it worked like a charm.
I also needed a t.join() at the end to prevent an execution error to happen.
i'm getting different std::thread behaviour running same app. on xcode or instruments (profiling), on xcode the single thread/multithread ratio is 0.6 and in instruments is 3.7 using a 4 thread array,
how is this possible?
Xcode run:
st...ok - lap: 4875 ms
st/8...ok - lap: 1205 ms
mt...ok - lap: 8330 ms
st/mt ratio:**0.6**
Instruments run:
st...ok - lap: 2182 ms
st/8...ok - lap: 545 ms
mt...ok - lap: 596 ms
st/mt ratio:**3.7**

function taking variadic number of initializer_lists with different types

NOTE: this question was caused by a bug in clang
In attemping to write a function taking an arbitrary number of intitializer_lists whose types need not match, I've stumbled upon a strange error:
template <typename... Ts>
void function(std::initializer_list<Ts> && ...args){
}
int main() {
function({1,2,3}, {'h', 'w'}, {"hello", "aloha"});
return 0;
}
The string literals cause a problem under clang but not under gcc with -pedantic -Wall -Wextra not warning about any extensions.
clang produces the error:
error: no matching function for call to 'function'
function({1,2,3}, {'h', 'w'}, {"hello", "aloha"});
^~~~~~~~
note: candidate function [with Ts = <int, char, char const[6]>] not
viable: no known conversion from 'const char [6]' to 'char const[6]' for
3rd argument
void function(std::initializer_list<Ts> && ...args){
^
So a few questions:
Is clang wrong for rejecting this or is gcc using an extension to deduce an initializer_list of arrays? Or is it deeper where gcc is just passing bad code?
Is this is the equivalent of passing an initializer_list of initializer_lists which is of course not allowed?
What is the difference between const char[6] and char const[6]?
Details:
clang version 3.4 (http://llvm.org/git/clang.git 9a65f4251fe5548e0b4478d584796ca84a6f5ebc) (http://llvm.org/git/llvm.git 4f67afc3d67d9a68f1b37767c9c2966a775186bd)
Target: x86_64-unknown-linux-gnu
Thread model: posix
gcc (Debian 4.7.2-5) 4.7.2
Debian 7
This is a bug in clang: it fails to perform the required array-to-pointer decay when deducing {"hello", "aloha"} against std::initializer_list<Ts>, but only when Ts is a parameter pack.
This program compiles fine:
#include <initializer_list>
template <typename T>
void function(std::initializer_list<T> il) {
}
int main() {
function({"hello", "aloha", "foobarbaz"});
}
but this program triggers the bug:
#include <initializer_list>
template <typename... T>
void function(std::initializer_list<T>... il) {
}
int main() {
function({"hello", "aloha", "foobarbaz"});
}
Edit: Could not find this bug in the LLVM bugzilla tracker, submitted as bug# 18047.

C++ casting issue

I have tried to compile this (--std=c++0x) using:
[FAIL with --std=c++0x flag] clang version 3.2-1~exp9ubuntu1 (tags/RELEASE_32/final) (based on LLVM 3.2)
[FAIL without --std=c++0x flag] clang version 3.2-1~exp9ubuntu1 (tags/RELEASE_32/final) (based on LLVM 3.2)
[FAIL without --std=c++11 flag] Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM
3.3svn)
[FAIL with --std=c++11 flag] Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM
3.3svn)
[PASS with --std=c++0x flag] gcc version 4.7.3 (Ubuntu/Linaro 4.7.3-1ubuntu1)
[FAIL without --std=c++0x flag] gcc version 4.7.3 (Ubuntu/Linaro 4.7.3-1ubuntu1)
When it fails at clang ubuntu, the following errors are produced:
test.cpp:26:37: error: no viable conversion from 'const P' to 'timeval'
return static_cast<timeval>(_p);
^~
/usr/include/x86_64-linux-gnu/bits/time.h:30:8: note: candidate constructor
(the implicit copy constructor) not viable: no known conversion from 'const P' to
'const timeval &' for 1st argument
struct timeval
^
/usr/include/x86_64-linux-gnu/bits/time.h:30:8: note: candidate constructor
(the implicit move constructor) not viable: no known conversion from 'const P' to 'timeval &&' for
1st argument
struct timeval
^
test.cpp:9:5: note: candidate function
operator const timeval() const {
^
test.cpp:13:5: note: candidate function
operator const int8_t() const {
^
I am not sure what I am doing incorrectly.
#include <iostream>
#include <cstdint>
union P {
timeval _timeval;
int8_t _int8_t;
uint8_t _uint8_t;
operator const timeval() const {
return _timeval;
}
operator const int8_t() const {
return _int8_t;
}
};
struct Y {
operator const int8_t() const {
return static_cast<int8_t>(_p);
}
operator const timeval() const {
return static_cast<timeval>(_p);
}
P _p;
};
int main()
{
Y testobj;
timeval ret = static_cast<timeval>(testobj);
return 0;
}
As a starting point, you're missing the # from the beginnings of your #includes.
#include <iostream>
#include <cstdint>
You're also not including any header that should define the type timeval. Given the system(s) you're apparently using, you probably want:
#include <sys/time.h>
If you were using Windows, that would probably be:
#include <winsock2.h>
There are probably more problems, but that should at least get you started in the right general direction.
You may need to remove the first const from the conversion operators, because you are trying to cast the union to a non-const value later:
operator timeval() const {
return _timeval;
}
Abusing conversion operators seems like a bad idea. If you want encapsulation, consider creating proper methods like timeval getTimeval() const.