-pedantic warning and pthread_create - c++

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

Related

How to fix warning "the compiler can assume that the address of 'object' will never be NULL"

I use gcc8 to compile this code:
#include <iostream>
class person
{
public:
virtual void setage()=0;
};
void test(person &object)
{
if (&object == NULL) {
std::cout << "NULL object1" << std::endl;
}
if (!(&object))
{
std::cout << "NULL object1" << std::endl;
}
}
int main()
{
person *object=NULL;
person &object1=*object;
test(object1);
}
Then, two warnings come out after compiling and running:
$g++ -std=c++14 -pthread -fgnu-tm -O2 -Wall -Wextra -pedantic -pthread
-pedantic-errors main.cpp -lm -latomic -lstdc++fs && ./a.out
main.cpp: In function 'void test(person&)':
main.cpp:11:17: warning: the compiler can assume that the address of
'object' will never be NULL [-Waddress]
if (&object == NULL) {
^
main.cpp:15:18: warning: the compiler can assume that the address of
'object' will never be NULL [-Waddress]
if (!(&object))
^
main.cpp:15:5: warning: nonnull argument 'object' compared to NULL
[-Wnonnull-compare]
if (!(&object))
^~
main.cpp:11:5: warning: nonnull argument 'object' compared to NULL
[-Wnonnull-compare]
if (&object == NULL) {
^~
Why is the address of object in function test not NULL even passing a NULL reference value to it?
It seems that reference object in function test can never be NULL, so we can just remove the code if (&object == NULL){...} and if (&object == NULL) {...} to avoid these two warnings, right?
Thanks for hints.
References are never null in a well-formed C++ program. The only valid way to initialize a reference is to bind it to a valid object. The only way a "null reference" may happen is if one derefernces a null pointer, as you have. But then the behavior of your program is undefined even before you check &object == NULL. The bug is in the code that passes the "null reference", and it must be fixed there.
So the compiler is warning you that you added a superfluous check, that protects you from little to nothing, because the broken code that needs to be fixed is outside your function.
Person* ptr_object = NULL;
Person& ref_object= *ptr_object;
By dereferencing ptr_object here you are dereferencing a NULL pointer, which is undefined behavior. A reference should not be referencing to NULL.

Trying to create posix thread and get invalid conversion from 'void*' to 'void* (__attribute__((__cdecl__)) *)(void*) error

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.

Getting error: ‘this’ is unavailable for static member functions even when function is not static

I have function, where I create new pthread and then work with it later
void Client::initialize(Client * c) {
//some unimportant code here
pthread_t thread;
pthread_create(&thread, NULL,
c->sendMessage, (void *) fd);
//some unimportant code here
}
Client::Client() {
initialize(this);
}
sendMessage function:
void * Client::sendMessage(void *threadid) {
//unimportant code here
this->showHelp();
//unimportant code here
return NULL;
}
declaration of showHelp
void Client::showHelp() {
//some code
}
When I try to compile it, I get this error:
g++ -Wall -pedantic -Wno-long-long -O0 -ggdb -pthread -lncurses -g -c ./Client.cpp
./Client.cpp: In static member function ‘static void* Client::sendMessage(void*)’:
./Client.cpp:244:13: error: ‘this’ is unavailable for static member functions
make: *** [Client.o] Error 1
How is that possible, when sendMessage is not declared as static ? Is there any way around?
Most likely your sendMessage is declared as static in class definition. Specific member function definitions are indistinguishable for static and non-static functions. You have to look at class definition to tell them apart.

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.

what is the error in my program?

I am trying to intercept libpthred( POSIX ) function calls using LD_PRELOAD technique. First I tried to create my own shared library having the same functin names as in the pthread library. Here is an example of my own created pthread_create function which first gets the address of original pthread_create function in the pthread library, then it calls the original function in the pthread library using the function pointer.
#include <stdio.h>
#include <dlfcn.h>
#include <pthread.h>
int pthread_create (pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void*), void *arg )
{
int return_value;
static int (*fptr) () = 0;
printf( "\n this is the test of LD_PRELOAD" );
char *lError = dlerror();
if( fptr == 0 )
{
fptr = ( int (*) () ) dlsym( RTLD_NEXT, "pthread_create" );
if( fptr == 0 )
{
(void) printf( "Error dlopen: %s", dlerror() );
return 0;
}
}
return (return_value);
}
I tried to compile it in this way:
g++ -fPIC -g -rdynamic -c -Wall ldtest.C -lrt -lpthread -ldl
But its giving the following error
ldtest.C:26: error: too many arguments to function
Line 26 is this line in the program.
return_value = (*fptr)( thread, attr, start_routine, arg );
Can anyone please tell me what is the problem here Or is this the right way to compile it?
There's no such line 26 in the code that you posted. Please, post relevant code.
If the fptr you use in line 26 is declared exactly as the one in your pthread_create above (i.e. with empty parameter list ()), then the code will not compile as C++, since in C++ the () as parameter list means "no parameters at all". And you are trying to pass arguments, which is what causes the error. Declare fptr with the proper parameter list if you want your code to work as C++.
The declaration with () as parameter list will work in C code, since in C it means "unspecified parameters", but not in C++.
You've declared fptr as a pointer to a function that takes no arguments and returns an int. Thus, gcc complains when you try calling it with three arguments.
Try redeclaring fptr with the proper arguments.