Dribbler
Dribbler

Reputation: 4681

signal in C++: using a member function

I have this problem with signal():

This code compiles fine:

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

void terminate( int param )
{
  printf ( "Terminating program...\n" );
  exit( 1 );
}

int main()
{
    signal( SIGTERM, terminate );
    return 0;
}

The following code, however, throws this error:

g++ -Wall -c -g goober.cpp
goober.cpp: In member function `void GOOBER::yarrgh()':
goober.cpp:5: error: argument of type `void (GOOBER::)(int)' does not match `
   void (*)(int)'
make: *** [goober.o] Error 1

goober.h:

#ifndef GOOBER_H
#define GOOBER_H

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

using namespace std;

class GOOBER {
public:
    GOOBER(){}
    ~GOOBER(){}
    void yarrgh();
    void terminate( int param );
};

#endif

goober.cpp:

#include "goober.h"

void GOOBER::yarrgh()
{
    signal( SIGTERM, terminate );
}

void GOOBER::terminate( int param )
{
    printf( "Terminating program...\n" );
    exit( 1 );
}

driver.cpp:

#include "goober.h"

using namespace std;

int main()
{
    GOOBER G;
    G.yarrgh();

    return 0;
}

I don't see any difference in the code, other than I'm calling signal() in a member. Any ideas what's wrong, and how to fix it?

Upvotes: 3

Views: 4783

Answers (4)

huubby
huubby

Reputation: 380

Member function have different signature from normal function that not belong any class. However, static member function have the same signature with normal function. So, you could declare your terminate member function in GOOBER class as static.

Upvotes: 2

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272497

I can tell you what's wrong:

You cannot use a non-static member function like a normal function pointer. Member functions always have an implicit this argument, which is provided (implicitly) by the caller. A C API cannot do this.

Upvotes: 7

Greg Hewgill
Greg Hewgill

Reputation: 993095

You need to declare your terminate() function as static:

class GOOBER {
    // ...
    static void terminate(int param);
};

This is because that as a non-static member function, the terminate() function expects to be passed the (hidden) this parameter to point to some instance of the object. Since the signal mechanism doesn't know about this (or about anything much of C++), you need to use a static function so that there is no hidden this parameter.

Upvotes: 15

Richard Pennington
Richard Pennington

Reputation: 19965

Terminate has to be a static function in the class.

Upvotes: 5

Related Questions