Accessing members inside struct with member function? [duplicate] - c

This question already has answers here:
How can I simulate OO-style polymorphism in C?
(13 answers)
Closed 6 years ago.
Suppose I have the following struct
struct Being{
int canFly;
int (*printFlying)();
}
And I want to do something like the following:
int main(){
struct Being * flyingThing = new_flyingThing();
struct Being * thingThatCantFly = new_Thing();
flyingThing->printFlying(); /* "I'm flying!" */
thingThatCantFly->printFlying(); /* "I can't fly!" */
}
It looks like I would need the printFlyingfunction to be able to access the canFly variable in the struct, but I don't know how to do this, or if this is possible.
Is there any way to get my code to do what I want? Thanks!!
I explained in the comments why this question is not a duplicate of the linked one.

C isn't an object-oriented language, so there's no automatic way for a function member to know which structure was used to call it.
Since each structure has its own function pointer, you can get the result you want by having them refer to different functions, which print the appropriate message, instead of getting it from the can_fly member.
int print_flying_thing() {
printf("I'm flying!\n");
}
struct Being *new_flyingThing() {
struct Being *thing = malloc(sizeof(struct Being));
thing->can_fly = 1;
thing->printFlying = print_flying_thing;
return thing;
}
int print_nonflying_thing() {
printf("I can't fly!\n");
}
struct Being *new_Thing() {
struct Being *thing = malloc(sizeof(struct Being));
thing->can_fly = 0;
thing->printFlying = print_nonflying_thing;
return thing;
}

The function pointed to by the printFlying pointer cannot access members of the containing struct Being structure unless it's given a parameter that refers to that structure. (Or it could access the structure in some other way, perhaps via a global variable, but a parameter is the cleanest way.)
Consider, for example, two objects of type struct Being, both having their printFlying pointer pointing to the same function. There's no way that function can tell which of the two objects it's associated with -- because it isn't associated with either of them.
C++ member functions can do that because they're given an implicit pointer parameter, referred to inside the function via the this keyword. C has no such feature.
You could probably create a macro that does something similar, but I doubt it would be worth the effort.
Have you considered just using C++?

For this particular example what you seem to really want is the ability to have a function pointer that points to two different functions, one to implement flying and one that implements not flying.
So the approach I would consider would be something like the following. I have not tried to actually compile this code but the sense of this is correct.
Also in your comments you mentioned about preventing changing the function pointer. You can do something like the following where a const is added to the struct definition for the function pointer and then using a clone of the struct with a cast.
Header file flying.h contents.
typedef struct _TAG_Being {
int (* const printFlying)();
} Being;
Being * new_flyingThing ();
Being * new_Thing();
Implementation or flying.c file.
#include "flying.h"
static int printFlyingThing()
{
printf (" I am a flying thing\n");
return 0;
}
static int printThing()
{
printf (" I am a thing\n");
return 1;
}
// use the same layout and members as Being above.
typedef struct {
int (* printFlying)();
} BeingX;
Being * new_flyingThing ()
{
BeingX *p = malloc(sizeof(BeingX));
p->printFlying = printFlyingThing; // use the flying thing function
{
Being *q = (Being *)p;
return q;
}
}
Being * new_Thing()
{
BeingX *p = malloc(sizeof(BeingX));
p->printFlying = printThing; // use the not flying thing function.
{
Being *q = (Being *)p;
return q;
}
}
Main or using .c file
#include "flying.h"
int main(){
Being * flyingThing = new_flyingThing();
Being * thingThatCantFly = new_Thing();
flyingThing->printFlying(); /* "I'm flying!" */
thingThatCantFly->printFlying(); /* "I can't fly!" */
}
If you have a need to access the actual Being object or variable in the printFlying() function then you will need to pass it as an argument.
For instance:
typedef struct _TAG_Being {
int xx;
int (*printFlying)(struct _TAG_Being *p);
} Being;
Then you would need something like:
Being * flyingThing = new_flyingThing();
flyingThing->printFlying(flyingThing); /* "I'm flying!" */

Related

How to pass a pointer to a struct declared inside another struct as a function parameter?

In one of my applications written in C I have a struct declared as a member of another struct:
struct _test
{
int varA;
//...
struct _small
{
int varB;
//...
} small;
} test;
Now I want to create a function that access varB above, but I don't want it to access the entire structure test, that is, I don't want to do:
#include <relevant_header>
void myFunction()
{
test.small.varB = 0;
}
instead, I want to pass only the small structure as a parameter to that function; something like this:
#include <relevant_header>
void myFunction(struct _test::_small* poSmall)
{
poSmall->varB = 0;
}
The problem is I don't know how to do this, that is, the above code doesn't compile right (I suppose it's C++ syntax only). So how may I do this in a C code - pass a pointer to a struct that was declared inside another struct? I wasn't able to find anything about this both in SO as well as in Google in general.
Just do:
void myFunction(struct _small *poSmall)
{
poSmall->varB = 0;
}
The scope of struct _small is not limited to its outer structure.

Understanding pointer structs in C

I am trying to understand an assignment I have before I have to take a final. I am trying to understand what exactly I am declaring.
So in a given file the typedef struct's are declared as so:
(Struct Declaration)
/** The following two structs must be defined in your <gamename>.c file **/
typedef struct game_position_t *game_position;
/* move struct must code enough information to reverse the move, given the resulting position */
typedef struct move_t *move;
I have then built the structs out as so (yes this has to be separated just because it is interfaced programming):
(Struct Definition)
/** The following two structs must be defined in your <gamename>.c file **/
struct game_position_t {
int mathy;
int numrows;
int *sizes;
};
/* move struct must code enough information to reverse the move, given the resulting position */
struct move_t {
int rownum;
int move_size;
};
Then an example of a functions and declaration of game_position for example is:
(Example Function)
/* return the starting position, NULL if error */
game_position starting_position(int me_first, int argc, char **argv) {
if (argc < 3) {
printf("\n\nToo few arguments, see help below\n\n");
game_help(argv[0]);
return NULL;
}
int mathy;
if (strcmp(argv[2],"search")==0)
mathy = 0;
else if (strcmp(argv[2],"mathy")==0)
mathy = 1;
else {
printf("\n\nSecond argument must be \"search\" or \"mathy\", see help below\n\n");
game_help(argv[0]);
return NULL;
}
int play_default = (argc==3);
if (play_default) printf("\n\nOK, we will play the default game of 7 5 3 1\n\n");
int defaultgame[4] = {7,5,3,1};
game_position result = malloc(sizeof(struct game_position_t)*1);
result->mathy = mathy;
if (result) {
result->numrows = (play_default ? 4 : argc-3);
result->sizes = malloc(sizeof(int)*(result->numrows));
int row;
for (row=0; row<(result->numrows); row++)
(result->sizes)[row] = (play_default ? defaultgame[row] : strlen(argv[row+2]));
}
return result;
}
So my main misunderstanding is when using a struct declaration in this manner, specifically putting the * before the name like this, typedef struct move_t *move;. Is that previous line saying move it a struct pointer or dereferencing move? Continuing from that. When defining them I just use the struct name such as struct move_t. I don't fully understand how they are linking together and in what matter. Then inside the function I just declare game_position, but still need to use a derefencer, 'p->`, to access it fields. So if someone could explain to me when these struct variables are points to structs and when they are the actual struct.
An example of my misunderstanding is that in the Example Function after result was declared. I first thought to use the . operator to access and set it's fields. I then changed it due to compiler errors, but now I want to understand my misunderstanding. And why did I I have to malloc game_position_t and not game_position?
typedef defines a type, so typedef struct move_t *move defines a new type named move, which is a pointer type, pointing to struct move_t. So after this if you define a variable with move ptr, ptr will have a pointer type so that you should use the syntax of accessing members through a pointer. When allocating memory for it, of course you have to specify the exact size of the structure other than the size of a pointer, that's sizeof(struct move_t)

multiple types in struct - C

I am new to C, and I am used to Java OOP. I have to use struct as holder for my global variables, that the system will write to/read from constantly.
I have 3 different types of variables in the struct, and I am not sure if that can cause a problem.
Also - do I need to declare the struct in the header file, in order to use it other C file ?
What will be the fastest and better way to access the variables from that struct in the different functions ? // The functions using these variables are in the same C file.
Here is the struct itself, that I made:
struct Data
{
double percentage_Height = 0;
double speed_Height = 0;
double time_Height = 0;
int distance_Height = 0;
double percentage_Distance = 0;
double speed_Distance = 0;
double time_Distance = 0;
int distance_Distance = 0;
uint16_t valueSpeed = 0;
double speedOfMotor = 0;
int tilt = 0;
};
and an example of a function that should use some of the fields of the struct:
int getHeight()
{
percentage_Height = getIncline()/90.0;
speed_Height = db_speed_sensor();
time_Height = 0.000027; // [h] , 100ms
distance_Height=0;
if (percentage_Height == 0)
{
percentage_Height = 1;
}
distance_Height = speed_Height * time_Height * percentage_Height * 100;
return distance_Height;
}
so what will be the best way to access these struct fields, instead of writing just the global vars?
EDIT: it is a real-time operating system, so tasks (smth like threads) will be accessing the data in the struct. I don't know if that makes any changes...
Define a global variable of type Data and access its members wherever you want.
struct Data GlobalData;
int getHeight()
{
GlobalData.percentage_Height = getIncline()/90.0;
GlobalData.speed_Height = db_speed_sensor();
....
}
If you want to use this in multiple files, better to define the structure in header file.
You have to declare the structure in a header file.
If an instance of this structure will be in the global scope, you have to define this instance in the global scope like this:
struct Data gData;
int getHeight()
{
gData.percentage_Height = getIncline()/90.0;
...
}
If your instance will be used only in the functions which are declared in the same file, you should define your variable like this:
static struct Data gData;
int getHeight()
{
gData.percentage_Height = getIncline()/90.0;
...
}
The keyword "static" means your variable is in the file scope (only visible in the file)
Yes, you should define the struct in a file and need to include it for its usage in other files. different datatypes in structure won't have any issue.
You can define functions separately to access the structure members and to process it. so that you don't need to repeat code. [ as like you did getHeight() ]. you can define those functions *inline*
to improve performance. (fastest way to access?) [only if the function is simple and (small in size)]
even you can use MACROS.
Use typedef for convenience.
typedef struct { ... } DATA;
so that code can be simplified. instead of writting
struct Data *s; simply put DATA *s;
you should use
s->structmember to process it.
Everyone has advised you to use a global structure. I would just like to add that, as you mentioned, all the functions accessing this structure are in one file, you should also declare a structure as static so that global structure will be limited file scope.
What will be the fastest and better way to access the variables from that struct in the different functions ? // The functions using these variables are in the same C file.
Using a pointer to that struct.
Example:
int getHeight(struct Data *data)
{
data->percentage_Height = getIncline()/90.0;
data->speed_Height = db_speed_sensor();
data->time_Height = 0.000027; // [h] , 100ms
data->distance_Height=0;
if (data->percentage_Height == 0)
{
data->percentage_Height = 1;
}
data->distance_Height = data->speed_Height * data->time_Height * data->percentage_Height * 100;
return data->distance_Height;
}
int main(int argc, char *argv[])
{
struct Data data;
load_data(&data); // function to initialize data
distance_Height = getHeight(&data);
return distance_Height;
}
Let the compiler decides when to inline those functions to improve performance, you should be worried about the readability and organization of your code.
Also - do I need to declare the struct in the header file, in order to use it other C file ?
If you want to direct access its members in other sources, you need to define it in a header, but you could just declare that you have that struct in you C, and create function to access the values of you struct. In this case you could define the struct only in the source file, and declare it in a header or any other source files you need this declaration.
Example:
file1:
#include <stdlib.h>
struct my_struct_s {
int value;
};
struct my_struct_s *create_my_struct(void)
{
return malloc(sizeof(struct my_struct_s));
}
void destroy_my_struct(struct my_struct_s *my_struct)
{
free(my_struct);
}
void set_my_struct(struct my_struct_s *my_struct, int value)
{
my_struct->value = value;
}
int get_my_struct(struct my_struct_s *my_struct)
{
return my_struct->value;
}
file 2:
#include <stdio.h>
#include <string.h>
struct my_struct_s;
struct my_struct_s *create_my_struct(void);
void destroy_my_struct(struct my_struct_s *my_struct);
void set_my_struct(struct my_struct_s *my_struct, int value);
int get_my_struct(struct my_struct_s *my_struct);
int main() {
struct my_struct_s *my_struct;
my_struct = create_my_struct();
set_my_struct(my_struct, 10);
printf("my_struct value = %d\n", get_my_struct(my_struct));
destroy_my_struct(my_struct);
return 0;
}
It would be better to have a header with the declarations needed to access the struct of file1, and include this header in file2, just made it this way to show you that it is possible, and maybe give you a clue about the difference between definition and declaration
A struct can hold any variety of types, no problem with how many variables you have in there as long as you have the memory for them.
You can declare a struct in a header file, but you will need to initialise it somewhere.
For example if you initialise it in a source file that is not your main and you still want to use it there, you will have to declare it in the main file with the keyword extern. Let me demonstrate:
file.h - a struct Foo is defined here
file.c - an instance of Foo named foo is initialised here with some values.
main.c - we want to use it here. In order to do that we put a statement for example right after the includes that reads extern struct Foo foo;
Or you can plain add file.h to your main.c file and just initialise it there.
Normally a struct variable is accessed like this: name_of_struct.member, e.g. struct.int_member = 42.
If you have a pointer to a struct and you try to modify the struct via the pointer there are two ways of doing this:
The more popular way:
ptr_to_struct->member = 42;
Or a more typical way for other types, but rather unusual in this case (at least for one level of dereference):
*ptr_to_struct.member = 42;
I would recommend that you pass the struct as an argument to the functions modifying it. Don't just use it as a plain global.

C find which pointer called function

Scenario:
There are multiple C structs, each of which contains a function pointer to the same function. These pointers can be different if necessary (pointers to pointers, etc.), but must all point, eventually, to the same function.
Problem:
When the function is called from one of the pointers, I need to retrieve, within the function, which struct it was called from.
e.g.
typedef struct A {
void * (*func)();
... /* Custom properties */
} * A;
typedef struct B {
void * (*func)();
... /* Custom properties */
} * B;
A a_init() {
A a;
... /* Custom initialisation, allocation, etc. */
a->func = myFunc;
return a;
}
B b_init() {
B b;
... /* Custom initialisation, allocation, etc. */
b->func = myFunc;
return b;
}
int main () {
A a = a_init();
void *something = a->func();
}
void * myFunc () {
// Need to get pointer to the instance of the struct this was called from here
}
Is there any way I can retrieve a pointer to the caller within myFunc? If necessary, I was thinking of creating pointers to pointers, etc. to the function, so each instance of an object would have a different pointer, and store all of them in a central location to match them up, but that obviously won't work if I can't even find the instance of the object or the pointer which was used. Any ideas?
Edit:
The question was intended a bit more broadly than I seem to have put it. Currying would be a great solution, if anyone has any ideas as to how to implement it in C. I had some ideas, but I just ended up coming right back to this spot with it.
I don't think there is any way within the language to do that, without explicitly passing some identifier (as an argument or a global) to myFunc. The address of a_init() exists somwhere within the call stack, but it's not accessible from the program.
It's like if somebody showed up at your door unannounced, how would you find out where that person came from without asking?
You can't do that. What you may do, however, is define your structs like this:
typedef struct A {
/* ... */
void *(*func)(void *);
} A;
typedef struct B {
/* ... */
void *(*func)(void *);
} B;
And your function like this:
void *myFunc(void *the_struct) {
/* ... */
}
And call like this:
A a = a_init();
void *something = a->func(a);
Alternatively, if you don't care about portability and for some reason need to be able to call it like a->func(), you may be able to create thunks/trampolines that add in the argument.
Can't be done.
In C++ when you call member functions the compiler implicitly adds this as the first function argument. Mimicking obj->method() syntax in C won't work because there's no implicit this.
This doesn't mean that OO is impossible in C, simply that you can't use the same syntax as C++ or Java do to it. It can still be done, but you have to be explicit:
void * myFunc (void *this) {
...
}
a->func(a);
b->func(b);

Functions in structure

Can structures contain functions?
No, but they can contain function pointers.
If your intent is to do some form of polymorphism in C then yes, it can be done:
typedef struct {
int (*open)(void *self, char *fspec);
int (*close)(void *self);
int (*read)(void *self, void *buff, size_t max_sz, size_t *p_act_sz);
int (*write)(void *self, void *buff, size_t max_sz, size_t *p_act_sz);
// And data goes here.
} tCommClass;
The typedef above was for a structure I created for a general purpose communications library. In order to initialise the variable, you would:
tCommClass *makeCommTcp (void) {
tCommClass *comm = malloc (sizeof (tCommClass));
if (comm != NULL) {
comm->open = &tcpOpen;
comm->close = &tcpOpen;
comm->read = &tcpOpen;
comm->write = &tcpWrite;
}
return comm;
}
tCommClass *makeCommSna (void) {
tCommClass *comm = malloc (sizeof (tCommClass));
if (comm != NULL) {
comm->open = &snaOpen;
comm->close = &snaOpen;
comm->read = &snaOpen;
comm->write = &snaWrite;
}
return comm;
}
tCommClass *commTcp = makeCommTcp();
tCommClass *commSna = makeCommSna();
Then, to call the functions, something like:
// Pass commTcp as first params so we have a self/this variable
// for accessing other functions and data area of object.
int stat = (commTcp->open)(commTcp, "bigiron.box.com:5000");
In this way, a single type could be used for TCP, SNA, RS232 or even carrier pidgeons, with exactly the same interface.
edit Cleared up ambiguity with the use of 'data types'
Not in C. struct types can only contain data.
From Section 6.7.2.1 of the ISO C99 Standard.
A structure or union shall not contain a member with incomplete or function type (hence,
a structure shall not contain an instance of itself, but may contain a pointer to an instance
of itself), except that the last member of a structure with more than one named member
may have incomplete array type; such a structure (and any union containing, possibly
recursively, a member that is such a structure) shall not be a member of a structure or an
element of an array.
No, you cannot. A structure cannot contain a declaration of a function but they can contain a definition of a function. A structure can only contain data types, pointers, pointers to different function. You can make a pointer to a function and then access from the structure.
#include<iostream>
#include<cstring>
using namespace std;
struct full_name
{
char *fname;
char *lname;
void (*show)(char *,char*);
};
void show(char *a1,char * a2)
{
cout<<a1<<"-"<<a2<<endl;
}
int main()
{
struct full_name loki;
loki.fname="Mohit";
loki.lname="Dabas";
loki.show=show;
loki.show(loki.fname,loki.lname);
return 0;
}
In C, structures are allowed to contain on data values and not the function pointers. Not allowed in C. but the following works literally fine when checked with gcc.
enter code here
#include <stdio.h>
struct st_func_ptr{
int data;
int (*callback) ();
};
int cb(){
printf(" Inside the call back \n");
return 0;
}
int main() {
struct st_func_ptr sfp = {10, cb};
printf("return value = %d \n",sfp.callback());
printf(" Inside main\n");
return 0;
}
So, am confused ...
It's all right.
In the linux kernel code,you will find many structures contain functions.
such as:
/*
* The type of device, "struct device" is embedded in. A class
* or bus can contain devices of different types
* like "partitions" and "disks", "mouse" and "event".
* This identifies the device type and carries type-specific
* information, equivalent to the kobj_type of a kobject.
* If "name" is specified, the uevent will contain it in
* the DEVTYPE variable.
*/
struct device_type {
const char *name;
struct attribute_group **groups;
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
void (*release)(struct device *dev);
int (*suspend)(struct device * dev, pm_message_t state);
int (*resume)(struct device * dev);
};
Yes its possible to declare a function and the function definition is not allowed and that should be the function pointer.
Its based on C99 tagged structure.
Lokesh V
They can, but there is no inherent advantage in usual C programming.
In C, all functions are in the global space anyway, so you get no information hiding by tucking them in a function. paxdiablo 's example is a way to organize functions into a struct, but you must see has to dereference each one anyway to use it.
The standard organizational structure of C is the File, with
the interfaces in the header and the implementations in the source.
That is how libc is done and that is how almost all C libraries are done.
Moder C compilers allow you to define and implement functions in the same source file, and even implement static functions in header files. This unfortunately leads to some confusion as to what goes where, and you can get unusual solutions like cramming functions into structs, source-only programs with no headers, etc.
You lose the advantage of separating interface from implementation that way.

Resources