Pointers to functions in structures trubble!

A

addinall

Hi guys and gals,

Haven't been in here for a good decade or so!
I'm having a braid-dead moment that is lasting for
a couple of days. Declaring pointers to functions
witrhin structures and accessing same....

This doesnt work. I thought it should. The compiler disagrees with me!
gcc32

-- lots of stuff like this

sparqbeat.c: In function `__life':
sparqbeat.c:1188: request for member `primary' in something not a
structure or union
sparqbeat.c:1190: request for member `open_server_socket' in something
not a structure or union
sparqbeat.c:1192: request for member `bind_server_socket' in something
not a structure or union
sparqbeat.c:1194: request for member `server' in something not a
structure or union
sparqbeat.c:1198: request for member `verbose' in something not a
structure or union
sparqbeat.c:1200: request for member `display' in something not a
structure or union
sparqbeat.c:1202: request for member `log_it' in something not a
structure or union
sparqbeat.c:1204: request for member `itoa' in something not a
structure or union
sparqbeat.c:1204: request for member `identity' in something not a
structure or union
sparqbeat.c:1204: request for member `scratch' in something not a
structure or union
sparqbeat.c:1205: request for member `me' in something not a structure
or union
sparqbeat.c:1210: request for member `verbose' in something not a
structure or union
sparqbeat.c:1212: request for member `display' in something not a
structure or union
sparqbeat.c:1214: request for member `log_it' in something not a
structure or union

---------

Any hints appreciated. I read the "variable arguments" thread,
and went back a few months looking for something similar.
Google returned 15,200,000 hits for
pointers to functions within structures


typedef struct __sparqbeat
{
int identity ; // my pid i
int child_identity ; // forked child pid
int error_number ; // current error state
int normal_pulse ; // pulse at rest, operation normal
int tachycardic ; // fast pulse, trying to recover
int port ; // what port to connect?
int time_of_death ; // how long 'till pronounced dead?
int beats ; // number of heartbeats since birth
int failures ; // number of failures since birth
int socket_fd ; // socket descriptor
int child_socket_fd ; // socket descriptor after fork
struct sockaddr_ini client_socket ; // client socket
structure
struct sockaddr_in server_socket ; // server socket structure

// 'encapsulated' functions

boolean ( *logging ) ( char * log_name ) = &__logging
;
void ( *log_it ) ( const char * err1, const char * err2,
const char * err3, const char * err4 ) = &__log_it ;
boolean ( *security_check) ( void ) = &__security_check ;
boolean ( *inherit ) ( void ) = &__inherit ;
boolean ( *birth ) ( int number_arguments, char ** arguments ) =
&__birth ;
boolean ( *triage ) ( void ) = &__triage ;
boolean ( *pulse ) ( void ) = &__pulse ;
boolean ( *life ) ( void ) = &__life ;
void ( *death ) ( char * eulogy ) = &__death ;
void ( *display ) ( char * message ) = &__display ;
void ( *usage ) ( void ) = &__usage ;
boolean ( *open_server_socket) ( void ) = __open_server_socket ;
boolean ( *bind_server_socket) ( void ) = &__bind_server_socket ;
boolean ( *open_client_socket) ( void ) = &__open_client_socket ;
boolean ( *connect_server) ( void ) = &__connect_server ;
void ( *shutdown_server) ( void ) = &__shutdown_server ;
void ( *shutdown_client) ( void ) = &__shutdown_client ;
void ( *server) ( void ) = &__server ;
void ( *client) ( void ) = &__client ;
void ( *send) ( int the_socket, char * ack ) = &__send ;
int ( *receive) ( int the_socket, char * peer_message ) = &__receive ;
char * ( *itoa) ( int value, char *string, int radix ) = &__itoa ;
boolean ( *ping_network) ( void ) = &__ping_network ;
boolean ( *ping_twin) ( void ) = &__ping_twin ;
boolean ( *read_config_file) ( void ) = &__read_config_file ;
} sparqbeat ;

sparqbeat * heartbeat ;


[....]

//-----------------------------
int main(int argc, char **argv)
{
if ( i_am_god() ) // need to be root for the
{ // tricks in this bad boy...
if ( new( heartbeat ) ) // allocate a new instance of the
{ // application object. Use heap
if ( heartbeat->birth( argc, argv ) ) // can the object birth
itself?
{ // if so, a long and happy life
heartbeat->life() ; // life handles the normal (should
be)
} // non-stop pulsing
else // but then again,
{ // birth failed, probably configuration
heartbeat->death( "Failed Birth" ) ; // other routines
will have written to
} // the .log files with detailed
} // information (depending on DEBUG level)
else // -----------------------------
{ // memory allocation failed, use the
printf( "Initial malloc FAIL" ) ; // routine printf. The
object
} // (and functions) are dead.(obviously)
} // -----------------------------
else // not root
{ // tell them
printf( "You must be root to run this utility" ) ;
} // and quit
// -----------------------------
clean_up() ; // look after memory, sockets and signals
// -----------------------------
return TRUE ; // ABEND is always abnormal, seek yea
} // the log files........bye


Ta.

Mark.
 
I

Ian Collins

Hi guys and gals,

Haven't been in here for a good decade or so!
I'm having a braid-dead moment that is lasting for
a couple of days. Declaring pointers to functions
witrhin structures and accessing same....
boolean ( *logging ) ( char * log_name ) = &__logging;

Boing! You can't do an assignment in a structure declaration.
 
A

addinall

Ian said:
Boing! You can't do an assignment in a structure declaration.

Very true! Stupid me.

I'm still having trubbles 'though after fixing that stuff-up.

The function.

//---------------------------------------
boolean new( sparqbeat * new_heartbeat )

// Allocate heap space for the major application object
// Return pass or fail condition

{
if ( new_heartbeat = malloc( sizeof( sparqbeat ) ) )
{
bzero( new_heartbeat, sizeof( sparqbeat ) ) ;
new_heartbeat->life = __life ;
// new_heartbeat->life = &__life ;
// new_heartbeat->life = &(__life);
return TRUE ;
}
else
{
return FALSE ;
}
}

t.c: In function `new':
t.c:177: warning: assignment from incompatible pointer type

In all instances.

Running the program just produces a segmentation fault.
I have done this before on a SCO system (good SCO in the old
days, not new EVIL SCO ;-), but I don't remember it being
this difficult.

Any futher pointers appreciated.
Cheese,
Mark.
 
I

Ian Collins

Very true! Stupid me.

I'm still having trubbles 'though after fixing that stuff-up.

The function.

//---------------------------------------
boolean new( sparqbeat * new_heartbeat )

// Allocate heap space for the major application object
// Return pass or fail condition

{
if ( new_heartbeat = malloc( sizeof( sparqbeat ) ) )
{
bzero( new_heartbeat, sizeof( sparqbeat ) ) ;
new_heartbeat->life = __life ;
// new_heartbeat->life = &__life ;
// new_heartbeat->life = &(__life);
return TRUE ;
}
else
{
return FALSE ;
}
}

t.c: In function `new':
t.c:177: warning: assignment from incompatible pointer type
What's the prototype for __life? Generally not a good idea to use '__'
at the beginning of a function name.
 
A

addinall

Ian said:
What's the prototype for __life? Generally not a good idea to use '__'
at the beginning of a function name.

Yeah. I thought an earlier prblem may have been name duplication
so.....

I got it to compile by...


typedef struct __sparqbeat
{
int identity ; // my pid i
int child_identity ; // forked child pid
int error_number ; // current error state
int normal_pulse ; // pulse at rest,
operation normal
int tachycardic ; // fast pulse, trying to
recover
int port ; // what port to connect?
int time_of_death ; // how long 'till
pronounced dead?
int beats ; // number of heartbeats
since birth
int failures ; // number of failures sice
birth


int verbose ; // noisy reporting
int do_as_i_say ; // force operation
regardless
int auto_flag ; // failover automatically
int primary ; // server or client?

void (*life ) ( void ) ;
void (*death ) ( char * eulogy ) ;

} sparqbeat ;

sparqbeat * heartbeat ; // major application object

//------------------------------
void __death( char * eulogy )

{
}


//--------------
void __life( void )

{
//if ( THIS->primary ) // if this is a server
{ // then
}
}



//---------------------------------------
boolean new( sparqbeat * new_heartbeat )

// Allocate heap space for the major application object
// Return pass or fail condition

{
printf(" in new" ) ;
if ( new_heartbeat = malloc( sizeof( sparqbeat ) ) )
{
printf(" after malloc " ) ;
bzero( new_heartbeat, sizeof( sparqbeat ) ) ;
printf(" after bzero " ) ;
new_heartbeat->life = &__life ;
new_heartbeat->death = &__death ;
printf(" after pointer allocationi " ) ;

return TRUE ;
}
else
{
return FALSE ;
}
}

//-----------------------------
int main(int argc, char **argv)
{
printf("Made it in " ) ;
if ( new( heartbeat ) ) // allocate a new
instance of the
{ // application object.
Use heap
heartbeat->life() ; // life handles the normal
(should be)
} // non-stop pulsing
else // but then again,
{ // birth failed, probably
configuration
printf( "Initial malloc FAIL" ) ; // routine printf. The
object
} // (and functions) are
dead.(obviously)
//
-----------------------------
return TRUE ; // ABEND is always
abnormal, seek yea

} // the log
files........bye
//--------------- EOF
--------------------------------------------------



So... it compiles and links without errors just on a simple

cc t.c -o t

Try to run it

../t
Segmentation fault.

Something is stuffed and I think it may be me! ;-)

Cheese,
Mark.
 
I

Ian Collins

Yeah. I thought an earlier prblem may have been name duplication
so.....

I got it to compile by...
new_heartbeat->life = &__life ;

The & isn't requited and you realy should remove the double underscore
from your names. All identifiers starting with double underscore are
reserved.
So... it compiles and links without errors just on a simple

cc t.c -o t

Try to run it

../t
Segmentation fault.

Something is stuffed and I think it may be me! ;-)
Star with a simple test case, like

#include <stdio.h>

void f() { puts("hello\n"); }

struct X
{
void (*fn)();
};

int
main()
{
struct X x;

x.fn = f;

x.fn();
}
 
A

addinall

Ian said:
The & isn't requited and you realy should remove the double underscore
from your names. All identifiers starting with double underscore are
reserved.

Star with a simple test case, like

#include <stdio.h>

void f() { puts("hello\n"); }

struct X
{
void (*fn)();
};

int
main()
{
struct X x;

x.fn = f;

x.fn();
}

Yeah. I did that, well I stripped out MOST of the functionality
of my application and tinkered with a shell.

I'm back playing with the big code now (it's a peer to peer
data synchronisation and high-availability failover utility).

For the life of me I dunno what is wrong/

All this works

typedef struct __sparqbeat
{
// ints and stuff

boolean ( * birth ) ( int number_arguments, char **
arguments );
/// etc
} sparqbeat ;

main()
{
sparqbeat.life = __life ;
sparqbeat.life() ;
// yada yada yada
}

no problems.

I wanted to have my object on the heap, hence

sparqbeat *heartbeat ;

and

sparqbeat->life = __life ;
sparqbeat->life() ;

# Segmentation error

?????

Dunno. I'm using the dot notation (running out of time
to fiddle ;-) but I'd like to know what is going on....

Cheers mate,
owe ya a beer! :)




 
G

Guest

boolean new( sparqbeat * new_heartbeat )

// Allocate heap space for the major application object
// Return pass or fail condition

How will the calling function be able to find the allocated object if
you don't return its address?
 
P

pemo

addinall said:
Yeah. I did that, well I stripped out MOST of the functionality
of my application and tinkered with a shell.

I'm back playing with the big code now (it's a peer to peer
data synchronisation and high-availability failover utility).

For the life of me I dunno what is wrong/

All this works

typedef struct __sparqbeat
{
// ints and stuff

boolean ( * birth ) ( int number_arguments, char **
arguments );
/// etc
} sparqbeat ;

main()
{
sparqbeat.life = __life ;
sparqbeat.life() ;
// yada yada yada
}

no problems.

I wanted to have my object on the heap, hence

sparqbeat *heartbeat ;


I'm guessing you *do* heartbeat = malloc(sizeof(*heartbeat)) somewhere
then - right?
 
C

Chris Dollin

boolean new( sparqbeat * new_heartbeat )

// Allocate heap space for the major application object
// Return pass or fail condition

{
if ( new_heartbeat = malloc( sizeof( sparqbeat ) ) )
{
bzero( new_heartbeat, sizeof( sparqbeat ) ) ;
new_heartbeat->life = __life ;
// new_heartbeat->life = &__life ;
// new_heartbeat->life = &(__life);
return TRUE ;
}
else
{
return FALSE ;
}
}

When the compiler errors get fixed:

You allocate store and then throw away the pointer - when the function
exits the value of `new_heartbeat` becomes inaccessible.
 
P

pemo

pemo said:
I'm guessing you *do* heartbeat = malloc(sizeof(*heartbeat)) somewhere
then - right?


Oh - I see new() does this - so shouldn't you be passing &heatbeat to new(),
i.e., a pointer to a pointer?
 
A

addinall

pemo said:
Oh - I see new() does this - so shouldn't you be passing &heatbeat to new(),
i.e., a pointer to a pointer?

Arrrrggggghhhhhhh!

Excuse me whilst I throw myself from the window ;-)))))))

Mark.
 
A

addinall

Chris said:
When the compiler errors get fixed:

You allocate store and then throw away the pointer - when the function
exits the value of `new_heartbeat` becomes inaccessible.

Yes. Thanks all for spotting my stupidity (senility ;-)

See ya in another 10 years!

Regards,
Mark.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top