POSIX Thread Addition on XCode - c++

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?

Related

Two different results passing pointer-to-array to a function in C and C++?

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);

Proper array type for execvp

I'm having difficulty figuring out exactly how to use execvp in C++. I'm not having any issues getting my code to work, but I'm specifically trying to figure out how to do it in a way that doesn't make the compiler complain.
I have looked at various questions on Stack Overflow and other resources, but I have been unable to find a solution that results in zero warnings from the compiler.
Consider the following C++ program, which prints its own source code:
#include <unistd.h>
int main(int argc, char *argv[])
{
char *args[3];
args[0] = "/bin/cat";
args[1] = __FILE__;
args[2] = NULL;
execvp(args[0], args);
return 0;
}
(I know that the return 0 should never be reached; I'm not so concerned with error handling in this question.)
When I compile it, the compiler emits two warnings:
$ g++ -Wall exec.cpp
exec.cpp: In function ‘int main(int, char**)’:
exec.cpp:6:15: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
args[0] = "/bin/cat";
^~~~~~~~~~
exec.cpp:7:15: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
args[1] = __FILE__;
^~~~~~~~
The compiled program successfully prints the source file. However, I'd really like to get the program to compile without any warnings. Since the compiler doesn't like that the string literals are being assigned to a pointer of type char* (not const char*), I suppose it would make sense to mark args as an array of const char* pointers. Consider this version of the program:
#include <unistd.h>
int main(int argc, char *argv[])
{
const char *args[3];
args[0] = "/bin/cat";
args[1] = __FILE__;
args[2] = NULL;
execvp(args[0], args);
return 0;
}
I would think that this program should compile and run with no warnings or errors, but the compiler does emit an error:
$ g++ -Wall exec.cpp
exec.cpp: In function ‘int main(int, char**)’:
exec.cpp:10:25: error: invalid conversion from ‘const char**’ to ‘char* const*’ [-fpermissive]
execvp(args[0], args);
^
In file included from exec.cpp:1:0:
/usr/include/unistd.h:581:12: note: initializing argument 2 of ‘int execvp(const char*, char* const*)’
extern int execvp (const char *__file, char *const __argv[])
^~~~~~
I also tried declaring args as char const *args[3], but the compiler emits the same error. The only way I am able to get it to compile with no warnings is by casting args in the call to execvp:
const char *args[3];
...
execvp(args[0], (char* const*)args);
This version compiles without warnings and runs successfully. However, I prefer to avoid casting when I can, because it makes it harder for me to reason about the type conversions going on.
Are one of the two working ways that I have shown above the best way to create an argument array to pass to execvp, or is there a better way that is clear and does not result in the compiler complaining?
I am using two different compilers - g++ 6.2.0 for native compilation on Ubuntu x86_64, and g++ 4.5.3 for cross compilation to an ARM platform.
Edit:
I do not believe that my question is a duplicate of this question. I understand the different effects of using const in different ways with respect to a char* variable. I am specifically asking which type is conventionally used for execvp calls, which is not answered by the linked question.

C++ in Ruby C extensions, pointer problems

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.

error: invalid conversion from ‘void*’ to ‘void* (*)(void*)’ - pthreads

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.

How pass vector<int> to pthread_create correctly in C++?

I would like to create a thread passing a vector as parameter.
but i got the following errors:
error: invalid conversion from ‘int’ to ‘void* (*)(void*)’ [-fpermissive]
error: initializing argument 3 of ‘int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)’ [-fpermissive]
I have the following code:
#include <iostream>
#include <vector>
#include <pthread.h>
using namespace std;
void* func(void* args)
{
vector<int>* v = static_cast<vector<int>*>(args);
cout << "Vector size: " << v->size();
}
int main ( int argc, char* argv[] )
{
vector<int> integers;
pthread_t thread;
for ( int i = 0; i < 10; i++)
integers.push_back(i+1);
// overheat call
//pthread_create( &thread, NULL, func, static_cast<void*>(&integers));
pthread_create( &thread, NULL,func,&integers);
cout << "Main thread finalized" << endl;
return 0;
}
How I can do it properly ?
Thanks
EDIT: forgot the includes posting here only; Revised.
I got new errors:
error: stray ‘\305’ in program
error: stray ‘\231’ in program
I am trying to know about it.
Thanks in advance.
FINAL EDIT : Thanks to all. Sorry, I had another int var called func in other location.
Thanks for your help.
You have forgotten to include <vector>; this confuses the compiler as it first fails to generate func, and then fails to identify it as a function in the call to pthread_create.
Once you include that, your code should compile (and you can remove the static_cast<void*> if you like); but to work correctly you also need to call pthread_join before the vector goes out of scope, and return a value from func.
UPDATE: your latest edit has broken the code: you should not cast func to void*, but leave it as a function pointer. This should work:
pthread_create(&thread, NULL, func, &integers);
Errors like stray ‘\305’ in program imply that you have some strange characters in your code, although they're not in the code you've posted. Have a look at the lines that the error messages refer to.