anisha#linux-y3pi:~> g++ conditionVarTEST.cpp -Wall
conditionVarTEST.cpp: In function ‘int main()’:
conditionVarTEST.cpp:33:53: error: invalid conversion from ‘void*’ to ‘void* (*)(void*)’
conditionVarTEST.cpp:33:53: error: initializing argument 3 of ‘int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)’
conditionVarTEST.cpp:34:53: error: invalid conversion from ‘void*’ to ‘void* (*)(void*)’
conditionVarTEST.cpp:34:53: error: initializing argument 3 of ‘int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)’
Line number 33 is this:
pthread_create (&A, NULL, (void *) &functionA, NULL);
Declaration of functionA is this:
void functionA (void*);
Its definition is:
void functionA (void* argA)
{
while (1)
{
pthread_mutex_lock (&mutexA);
if (count < 0)
{
pthread_cond_wait (&conditionVariableA, &mutexA);
}
else
{
// Do something.
std :: cout << "\nTime to enjoy!";
}
pthread_mutex_unlock (&mutexA);
}
}
If you look at the manual page you will see that the function argument is
void *(*start_routine) (void *)
That is, a pointer to a function which takes one void * argument and returns void *.
To get rid of your errors, change your function to return void *, and pass it without type-casting it. The return from the thread function can be a simple return NULL if you don't care about the value.
(void *) &functionA will cast your function pointer functionA which is of type void (*)(void*) to a simple void*. The later can't be converted to the first again, so the compiler reports an error. This is one of the reasons why you shouldn't use C-style casts.
Use pthread_create (&A, NULL, functionA, NULL); instead.
Also, the return type of a thread function should be void*, not void. So change void functionA(void*) to void* functionA(void*).
Use
pthread_create (&A, NULL, functionA, NULL);
instead of casting.
Also the function you use to pass to pthread_create should return a void* so to avoid any problems later, consider changing the function signature to accomodate this.
And as you are using a C++ compiler, you should use a function with C binding, as pthread_create expects a C function:
extern "C" void* functionA (void*);
C++ and C may have the same calling conventions on your current platform, but there is no guaranty, that this will be the case on other platforms or will be so in the future.
Related
I have a question regarding to the code snippet appended below. Anyway I ran the snippet on ideone.com and got two different results
C: Succeed.
C++: Error:
prog.cpp: In function ‘int main()’:
prog.cpp:20:13: error: cannot convert ‘int* (*)[2][10]’ to \
‘int* (*)[10]’ for argument ‘1’ to ‘void foo(int* (*)[10], size_t)’
foo(&a, LEN);
^
The result in C++ is what I expect, but it runs successfully in C, and it seems like it's compiler dependent because people on the chat helping ran the snippet only got a warning.
So which part I've missed? Is that C automatically did some conversion?
#include <stdio.h>
#include <stddef.h>
#define LEN 2
void foo(int* a[][10], size_t len) {
printf("%s\n", "successfully called foo.");
}
int main(void) {
// a is an LEN-array of an 10-array of (int *)
int *a[LEN][10] = {{0}};
// but the identifier `a` will decay to be a pointer of type int*[10]
// p1 is a pointer to an 10-array of (int *)
int *(*p1)[10] = 0;
foo(a, LEN);
foo(&a, LEN);
return 0;
}
Drastic edit; previous answer was wrong as pointed out in the comments.
The program is ill-formed in both C and C++. But the standards of the respective languages don't disallow successfully compiling programs that violate the imposed constraints. This allows the implementations to extend the language. Implementations are merely required to issue a diagnostic message. Both a warning and an error are conforming behaviours.
For whatever reason, the compiler that you use (through ideone) has chosen to behave differently when compiling C++.
This is not valid in C. Using gcc with -Wall -Wextra, it outputs the following:
x1.c: In function ‘main’:
x1.c:19:9: warning: passing argument 1 of ‘foo’ from incompatible pointer type [-Wincompatible-pointer-types]
foo(&a, LEN);
^
x1.c:5:6: note: expected ‘int * (*)[10]’ but argument is of type ‘int * (*)[2][10]’
void foo(int* a[][10], size_t len) {
^~~
The types are not compatible. It only shows up as a warning because C tends to allow various pointer conversions even though they aren't proper.
You can however do this:
int *(*p1)[10] = a;
foo(a, LEN);
foo(p1, LEN);
Sorry if I'm not as descriptive as I should be, I'm nearly asleep as I type this. I am trying to create a posix thread in my c++ code compiling with g++ on mingw. Here's the except of the code I'm trying to compile
static void processNextNodeOnQueue(queue<TreeNode*> &toComputeQueue) {...}
void static processNodes(void* ptr) {
pair<queue<TreeNode*>*, bool*> *input = (pair<queue<TreeNode*>*, bool*>*) ptr;
while(*(input->second)) {
pthread_mutex_lock(&mutex1);
if(input->first->empty()) return;
pthread_mutex_unlock(&mutex1);
processNextNodeOnQueue(*(input->first));
}
}
void startThinking() {
thinking = true;
mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_t thread;
pair<queue<TreeNode*>*, bool*> *input = new pair<queue<TreeNode*>*, bool*>(&toComputeQueue, &thinking);
int thereadId = pthread_create(&thread, NULL, (void*)&processNodes, (void*) input );
delete input;
}
void stopThinking() {
//set thinking to false and wait for threads to wrap up
thinking = false;
}
void processForTime(double seconds) {
clock_t t;
int f;
t = clock();
startThinking();
//something to wait for an amount of time
stopThinking();
}
Here's the full compiler output in case I missed something
C:\Users\Maxwell\SkyDrive\RPI\Fall 2013\IHSS-1964\Connect 4\MaxAI>g++ -g -pthread -std=c++11 -o3 *.cpp -o Max.exe
In file included from unit_tests.h:5:0,
from main.cpp:11:
search_tree.h: In member function 'void BoardSearchTree::startThinking()':
search_tree.h:221:85: error: invalid conversion from 'void*' to 'void* (__attribute__((__cdecl__)) *)(void*)' [-fpermissive]
int thereadId = pthread_create(&thread, NULL, (void*)&processNodes, (void*) input );
^
In file included from search_tree.h:12:0,
from unit_tests.h:5,
from main.cpp:11:
c:\mingw\include\pthread.h:940:31: error: initializing argument 3 of 'int pthread_create(pthread_t*, pthread_attr_t_*const*, void* (__attribute__((__cdecl__)) *)(void*), void*)' [-fpermissive] PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid,
The third parameter to pthread_create is a void *(*start_routine) (void *) - a function pointer. You are casting the function to a (void*) which is both unnecessary and incorrect. Just remove the cast:
pthread_create(&thread, NULL, processNodes, (void*) input );
Also since input is a pointer you don't need to cast it either, all pointers (save pointers-to-members) are implicitly convertible to void*):
pthread_create(&thread, NULL, processNodes, input );
Assuming you're using the pthread-w32 library from here, then the following header information is relevant:
#define PTW32_CDECL __cdecl
PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid,
const pthread_attr_t * attr,
void *(PTW32_CDECL *start) (void *),
void *arg);
What this shows is that the start parameter should be a function pointer that uses the __cdecl calling convention.
Try changing your processNodes function prototype to the following:
static void PTW32_CDECL processNodes(void* ptr)
The compiler should then create your thread function with the correct calling convention as expected by pthread_create.
I'm tryign to build a Ruby C extension that uses some c++ libraries. Problem is I can't even get a simple "hello world" to work.
//hello_world.cpp
#include <ruby.h>
static VALUE tosCore;
static VALUE my_function( VALUE self )
{
VALUE str = rb_str_new2( "Hello World!" );
return str;
}
extern "C"
void Init_hello_world( void )
{
tosCore = rb_define_module("Core");
rb_define_module_function(tosCore, "my_method", my_function, 0);
}
The output I get is
compiling hello_world.cpp
hello_world.cpp: In function 'void Init_hello_world()':
hello_world.cpp:17:67: error: invalid conversion from 'VALUE (*)(VALUE) {aka lon
g unsigned int (*)(long unsigned int)}' to 'VALUE (*)(...) {aka long unsigned in
t (*)(...)}' [-fpermissive]
In file included from c:/Ruby200/include/ruby-2.0.0/ruby.h:33:0,
from hello_world.cpp:2:
c:/Ruby200/include/ruby-2.0.0/ruby/ruby.h:1291:6: error: initializing argument
3 of 'void rb_define_module_function(VALUE, const char*, VALUE (*)(...), int)'
[-fpermissive]
make: *** [hello_world.o] Error 1
I'm no C/C++ expert. Ruby is my language. I have compiled a few thousand lines of C++ under Rice with no problem, but since I want this particular extension to compile under Windows, Rice is not an option.
It's because the function callback you present to rb_define_module_function is not what the compiler expects. It want a function looking like this:
VALUE my_function(...)
But your function is
VALUE my_function( VALUE self )
Notice the difference in the argument list.
One way to get rid of the error, is to type cast the argument to the type that rb_define_module_function expects:
rb_define_module_function(tosCore, "my_method",
reinterpret_cast<VALUE(*)(...)>(my_function), 0);
You can read about reinterpret_cast here.
I'm newbie in the ansi and iso world, i compiled my program with :
-asni -pedantic -std=c++11 -std=c++98
Now, i get the following warning:
warning: converting from 'void (NetworkSocket::*)()' to 'void* (*)(void*)' [-pedantic]
for the following line:
if (pthread_create(this->threadArray, NULL, (void*(*)(void*)) &NetworkSocket::threadProcedure , (void *)this) != 0)
{ /* error */ }
How can i pass pedantic warning?
pthread_create is a C function expecting a C function taking a void pointer, and returning a void pointer. So you can use such a C function to dispatch the call to you member function, if you use the this pointer as thread argument:
extern "C" void* startThread( void* p )
{
static_cast< NetworkSocket* >( p )->threadProcedure();
return 0;
}
if ( pthread_create( this->threadArray, 0, startThread, this ) )
...
The program should get arguments from a command line, and add the arguments via posix threads. But Xcode successfully builds it, but gives no output. Is there something wrong with this code.
Thanks
#include <iostream>
#include <pthread.h>
using namespace std;
void *Add(void *threadid){
long tid;
tid =(long)threadid;
long sum=0;
sum=sum+tid;
printf("%ld.\n",sum);
pthread_exit(NULL);
}
void *Print(void *threadid){
long tid;
tid =(long)threadid;
printf("%ld.\n",tid);
pthread_exit(NULL);
}
int main (int argc, char const *argv[])
{
if(argc<6){
printf("you need more arguments");
return -1;
}
long real[5];
pthread_t athread,bthread;
for (int x=1;x<=5;x++)
real[x-1]=atol(argv[x]);
for(int y=1;y<=5;y++)
pthread_create(athread[y],NULL,Add,(void *)&real[y]);
for(int y=1;y<=5;y++)
pthread_create(bthread[y],NULL,Print,(void *)&real[y]);
pthread_exit(NULL);
return 0;
}
First of all I think you should check if pthread_create method was success.
I don't have expirience in pthread under Apple, but based on that code I think you have problem with thread creation.
First of all, printf is defined in stdio.h and not in iostream. If you'd like to do it the C++ way with iostream, then cout << "Blabla " << var << endl; should be used instead.
Second, you are calling pthread_create with wrong arguments. As defined athread and bthread are not arrays but you use them as such. I am not entirely sure why this would even compile since pthread_create expects pthread_t* as first argument and you are providing *pthread_t. If the code ever compiles, it will most likely crash when run.
Third, you are not joining the adder threads. This means that your print threads could start before the adder threads have finished.
Fourth, you are summing into local variables. You are supposed to sum into a global one. Don't forget to guard the access to it by a mutex or something.
Fifth, arguments to the thread routines are wrong. You are passing pointer to the value and not the value itself and later reinterpreting the pointer as the value itself. You would most likely want to use (void *)real[y] and not (void *)&real[y]. Mind that casting long to void * doesn't work on all systems. On Mac OS X both long and void * are of the same length (either 32 or 64 bits) but this is not true in general.
Edited: Your code doesn't even compile on OS X:
$ g++ -o t.x t.cpp
t.cpp: In function ‘int main(int, const char**)’:
t.cpp:37: error: cannot convert ‘_opaque_pthread_t’ to ‘_opaque_pthread_t**’ for argument ‘1’ to ‘int pthread_create(_opaque_pthread_t**, const pthread_attr_t*, void* (*)(void*), void*)’
t.cpp:40: error: cannot convert ‘_opaque_pthread_t’ to ‘_opaque_pthread_t**’ for argument ‘1’ to ‘int pthread_create(_opaque_pthread_t**, const pthread_attr_t*, void* (*)(void*), void*)’
$ clang -o t.x t.cpp
t.cpp:37:5: error: no matching function for call to 'pthread_create'
pthread_create(athread[y],NULL,Add,(void *)&real[y]);
^~~~~~~~~~~~~~
/usr/include/pthread.h:304:11: note: candidate function not viable: no known
conversion from 'struct _opaque_pthread_t' to 'pthread_t *' (aka
'_opaque_pthread_t **') for 1st argument;
int pthread_create(pthread_t * __restrict,
^
t.cpp:40:5: error: no matching function for call to 'pthread_create'
pthread_create(bthread[y],NULL,Print,(void *)&real[y]);
^~~~~~~~~~~~~~
/usr/include/pthread.h:304:11: note: candidate function not viable: no known
conversion from 'struct _opaque_pthread_t' to 'pthread_t *' (aka
'_opaque_pthread_t **') for 1st argument;
int pthread_create(pthread_t * __restrict,
^
2 errors generated.
Don't you even see the error messages that XCode is providing?