Access from function in struct (pointer to function) to other items in the struct (advanced)

O

Ole

hello,

Little problem:

struct operatable {
char * operatable_id;
int ( * delegate ) ( ... );
somedatatype data;
};

When i now have designed a function to int (*delegate)() and i call it

struct operatable * t = ( struct operatable * ) malloc (
sizeof( struct operatable )
);

t->delegate( someargumenttype arg );

How then is it possible to do something like this:

int delegate_impl ( someargumenttype arg ) {
// do something with arg, parse etc.
printf ( "Called delegate() from within : %s\n",
<reference_on_containingstruct>->operatable_id
);
}
 
X

xarax

Ole said:
hello,

Little problem:

struct operatable {
char * operatable_id;
int ( * delegate ) ( ... );
somedatatype data;
};

When i now have designed a function to int (*delegate)() and i call it

struct operatable * t = ( struct operatable * ) malloc (
sizeof( struct operatable )
);

t->delegate( someargumenttype arg );

How then is it possible to do something like this:

int delegate_impl ( someargumenttype arg ) {
// do something with arg, parse etc.
printf ( "Called delegate() from within : %s\n",
<reference_on_containingstruct>->operatable_id
);
}

You would have to pass the struct pointer as
part of the function parameter list (most likely
the first parameter, because it's always required).
 
M

Michael Wojcik

struct operatable {
char * operatable_id;
int ( * delegate ) ( ... );
somedatatype data;
};

I assume "..." above is actually replaced with a real parameter
list. C variadic function notation requires at least one non-
variadic parameter. A function pointer type with an argument list
of "(...)" is illegal.
When i now have designed a function to int (*delegate)() and i call it

You mean you've assigned a value to "delegate"?
struct operatable * t = ( struct operatable * ) malloc (
sizeof( struct operatable )
);

I hope this comes *before* you assign anything to "delegate". Also,
note that you should not cast the return value of malloc, and it's
safer to apply the sizeof operator to the dereferenced pointer than
to its type, since the latter may change in a later version of the
program:

#include <stdlib.h>
struct opertable *t = malloc(sizeof *t);

And then check for malloc failure.
t->delegate( someargumenttype arg );

OK, if the definition of struct opertable actually has something like

int (*delegate)(someargumenttype);
How then is it possible to do something like this:

int delegate_impl ( someargumenttype arg ) {
// do something with arg, parse etc.
printf ( "Called delegate() from within : %s\n",
<reference_on_containingstruct>->operatable_id
);
}

This is not entirely clear. If you intend to use delegate_impl as
a possible value for your delegate field, then it will not have
access to the struct opertable * variable through which it was
called. If you want such access, you'll have to pass it. For
example:

struct operatable
{
char *operatable_id;
int (*delegate)(struct opertable *, somedatatype);
somedatatype data;
};

int delegate_impl(struct opertable *caller, somedatatype arg)
{
/* ... */
printf("Called delegate from %s\n", caller->opertable_id;
return 0;
}

By the way, putting whitespace between the "*" and the identifier
name when specifying pointer types is a bad idea. It can lead to
errors like:

char * pointer1, pointer2;

where "pointer2" is in fact a char, not a char *, despite its name.
 
O

Ole

I assume "..." above is actually replaced with a real parameter
list. C variadic function notation requires at least one non-
variadic parameter. A function pointer type with an argument list
of "(...)" is illegal.

Yes. I know that the variable argument list can only be defined, when
at least
one memory address of a given argument is available. With (...) i
meant, that the arguments are not essential for this problem.
You mean you've assigned a value to "delegate"?
Yes. I meant to pass a function pointer to the "delegate" variable.

By the way, is

int ( * delegate ) ( int x, ... );

still a variable? I would say it is, since pointers are only variables
that
can hold memory a address.
I hope this comes *before* you assign anything to "delegate". Also,
note that you should not cast the return value of malloc, and it's
safer to apply the sizeof operator to the dereferenced pointer than
to its type, since the latter may change in a later version of the
program:

#include <stdlib.h>
struct opertable *t = malloc(sizeof *t);

And then check for malloc failure.


OK, if the definition of struct opertable actually has something like

int (*delegate)(someargumenttype);


This is not entirely clear. If you intend to use delegate_impl as
a possible value for your delegate field, then it will not have
access to the struct opertable * variable through which it was
called. If you want such access, you'll have to pass it. For
example:

struct operatable
{
char *operatable_id;
int (*delegate)(struct opertable *, somedatatype);
somedatatype data;
};

int delegate_impl(struct opertable *caller, somedatatype arg)
{
/* ... */
printf("Called delegate from %s\n", caller->opertable_id;
return 0;
}

By the way, putting whitespace between the "*" and the identifier
name when specifying pointer types is a bad idea. It can lead to
errors like:

char * pointer1, pointer2;

where "pointer2" is in fact a char, not a char *, despite its name.

But that's not an error. It defines a variable that can hold a memory
address to
a char and a variable that holds a char. I don't exactly know the
C-Coding Guidelines, but i prefer to put some space between all tokens
in order to
render the code more readable. Ok, it may mislead. With this, i agree.

To the main problem: i wanted to return to C-Style for developing a
some server-core-components. Coming from Perl/Java, i want to test the
boundaries of
the C-Language-functionalities. (Java to C because Java cannot be
sufficiently observed, from the systems administrator's point of view.
How many java apps(server apps) must be rebooted due to misallocated
JVM memory? But this is offtopic.)

I have to (re)reorient a bit, when returning to C.

So, in a procedural language like c i have to achieve that kind of
functionality
by passing args to the function.

Thanks for the hints.
Ole
 
M

Michael Wojcik

Yes. I meant to pass a function pointer to the "delegate" variable.

By the way, is

int ( * delegate ) ( int x, ... );

still a variable? I would say it is, since pointers are only variables
that can hold memory a address.

It declares a variable named "delegate" of type "pointer to function
taking an integer and a variadic argument list and returning an int".
In other words, I think the answer to your question is "yes", more or
less. You're correct that pointers, including function pointers, are
variables.
But that's not an error. It defines a variable that can hold a memory
address to a char and a variable that holds a char.

Ah, but it is an error. Source code has two audiences: programmers
and language implementations. It must speak accurately to both.
Even if this fragment contains no C errors, it still contains an
error in its representation of the program to programmers, because
the name of the "pointer2" variable belies its type.
I don't exactly know the
C-Coding Guidelines,

There are guidelines and guidelines; none have any force other than
opinion, but some of them are better-informed and justified opinions
than others. Agreement is fairly widespread on this particular
point (not separating the "*" and the identifier name when declaring
pointers).
To the main problem: i wanted to return to C-Style for developing a
some server-core-components. Coming from Perl/Java, i want to test the
boundaries of the C-Language-functionalities.

I have to (re)reorient a bit, when returning to C.

So, in a procedural language like c i have to achieve that kind of
functionality by passing args to the function.

That's correct. Typically OO languages "invisibly" pass a reference
to the calling object to the method it invokes. In C you have to do
that explicitly, because the language doesn't do it for you. Simple
as that.

If you'd prefer a language with built-in OO support, there's always
C++, of course. Just like C except for a handful of subtle differences
and several tons of baggage piled on top. Combines C's safety and
ease of use with Perl's clarity and maintainability.

--
Michael Wojcik (e-mail address removed)

There are many definitions of what art is, but what I am convinced art is not
is self-expression. If I have an experience, it is not important because it
is mine. It is important because it's worth writing about for other people,
worth sharing with other people. That is what gives it validity. (Auden)
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top