typedef struct data * Data;
I have something like this that I don't understand. I have some function later on that returns Data. What I don't get is, data * Data seems to me like a "empty" struct .. It doesn't have anything in it.
So what do I create when I do something like Data d; and what do I returns from function if this struct is empty?
Thank you.
That line of code is creating a type alias. It means that Data is an alias for the type struct data *. So, whenever you see Data, it's as if you saw a pointer to struct data.
When you do something like Data d;, you're basically declaring a pointer to struct data. You're not initializing the pointer, so it doesn't point to a valid struct data. Dereferencing the pointer will thus be invalid.
When you have a variable of type Data, you need to point it to somewhere valid before trying to dereference it.
Perhaps a less confusing approach would have been to do it like this instead:
typedef struct data *Data_ptr;
Which at least would convey the idea that Data_ptr is a pointer type alias.
You are looking at an opaque pointer.
Which means that the structure details are hidden to you, but the library functions that are using it are aware of the true content of the struct.
This type of declaration is usually made in public header files, while more private implementation use a complete declaration of the struct.
Related
I'm trying to implement a static linked list in C that holds any data type. I know that the node struct should use a void* but I also want each list to hold the same data type. That is, lists can hold any data type but every item in the list must be of the same type. I know using void* allows nodes to have any data type but how do I make it so that a list only contains items of the same type?
You can use the macro system to handle non void * lists... if you do something like:
#define LIST_OF(_type) struct node_of_##_type { \
struct node_of_##_type *prev, *next; \
_type data; \
}
then, you can declare as many list types as you want, you have only to say something like:
typedef char *string;
LIST_OF(string) *my_list = NULL;
/* will expend to something similar to:
struct node_of_string {
struct node_of_string *prev, next;
string data;
} *my_list = NULL;
*/
This is an attempt (well, too far yet to be comparable) to emulate the templates of C++. You will not have a list capable of storing anything, but a list adapted only to one type (but any type that can be typedef'd, as the type parameter must be a typename, not a type specification. And, as in C++, once you have that you have to instantiate every function using that type, to the proper type, forcing you to name it, (as functions cannot be overloaded in C) and to rewrite (by means of more macro expansions) to the actual code. Things get complicate soon, making it necessary some help from the language to use OOP techniques in C.
The problem with C is that it is a weakly typed language, this means that you can cast a Banana to a Truck and the compiler will be totally fine with that. Programmers in C are conditioned to keep this in mind and be very wary of what they are doing, that is to say it is the programmers responsibility to "think ahead" and make no such mistakes (e.g. like putting a Banana in a list of Trucks). You could work around this by adding another layer between your datatypes and the list nodes. A trust could hold a void* to the actual type together with an enum or an integer value representing the id of the data type you are trying to store in the list, you could call this a tagged node or something. The issue now becomes how to retrieve that tag or enum value. This will sadly add some boilerplate to your program, however, this might be automated using macro's.
Note that the problem you are highlighting (weak typing) is just part of the quirkiness of C. what I usually do in these situations is naming the variable holding the list accordingly and think very carefully of what I am doing with this variable.
A solution may be to, instead of using a List, use an array, this will at least produce a segmentation fault in some scenario's, but that will also be the case if you cast a Truck to a Banana and try to access fields which are out of memory range...
Hope this helps!
I've use quite a bit of JavaScript so far. If you were to use an object constructor in JavaScript, you have access to the this constructor.
So my question relates to trying to use a similar concept in C. I created a struct that I want to be able to self reference:
struct Storage {
void (*delete)();
}
So if I were to allocate a Storage class:
struct Storage *myStruct = malloc(sizeof(struct Storage));
Let's say I'm trying to delete myStruct. If I have some delete function that I point to (with myStruct->delete = deleteStructure), I would like to do something like this:
myStruct.delete();
which would then free() the struct through a self referencing variable inside of said delete function. I'm wondering if there would be a way to have the delete function look like:
void deleteStructure() {
free( /* "this" or some equivalent C self-reference */ );
}
My assumption from research so far is that this is not possible since this is usually only in object oriented programming languages. If this is not possible, I'm wondering what would be the semantically correct way to do this. I'm hoping to make the usage of this delete functionality rather simplistic from a user interface perspective. The only way I understand this to work would be passing a reference to the structure like:
void deleteStructure(struct Storage *someStructure) {
free(someStructure);
}
which would then require deletion to be done as follows:
deleteStructure(myStruct);
To sum up: is there a way to make a delete function that uses self references in C, and if not, what would be the most semantically correct way to delete a structure in the most user friendly way?
No. You cannot even define a function for a struct.
struct Storage {
void (*delete)();
}
simply stores a pointer to a void function. That could be any void function and when it is being called, it has no connection to Storage whatsoever.
Also note that in your code, every instance of the struct stores one pointer to a void function. You could initialize them so that they all point to the same function, in which case you would simply waste 64 bit per instance without any real benefit. You could also make them point to completely different functions with different semantics.
As per #UnholySheep's comment, the correct semantical use of a struct with connection to a C function will follow the structure:
struct Storage {
/* Some definitions here */
}
void deleteStructure(struct Storage *someStructure) {
free( /* all inner structure allocations */ );
free(someStructure);
}
Here's more about passing structs by reference.
I'm writing a C library, and have a struct that looks (roughly) like:
struct Obj {
char tag,
union {
int i,
void *v
} val
};
I do not want to expose the internals of this struct through the API, because users do not need to know the implementation and they could change in future versions. Users can interact with the struct via functions in the API.
I used incomplete types in the header for other, larger types in my API, which can only be accessed via pointer by the user. I do not want to restrict users to accessing Obj via pointer, as Obj will likely only be 16 bytes maximum.
I have not been able to use an incomplete type here, because I do not know of a way to expose only the size of the struct to users, without fields.
My question is:
Is there a way to expose a type with size only in C (no knowledge of the fields in the struct given to user), some other hack to accomplish what I want, or should I implement this in some completely different way?
Please comment if I haven't provided enough details or anything is unclear.
The standard pattern for this is to create a function which allocates the struct for the user:
struct Obj* obj_new(void) {
return malloc(sizeof(struct Obj));
}
Then just leave the type as incomplete in your public header.
Of course, if you really want to expose only the size, you could just create a function which returns sizeof(struct Obj). Obviously people can misuse it (e.g., hardcoding the value into their code as an "optimization" to avoid calling that function), but that's not on you. It is something that is done occasionally, usually to help facilitate inheritance.
I have a very basic question. In C, we declare a structure like so:
Snippet 1:
struct node {
int a;
int b;
char c;
};
I understand the basic concept behind structures. It can be viewed from many angles. It's a "structure", it is used to create a user defined type.
A structure is useless unless we define objects for it. We can create objects for it like so:
struct node obj1;
obj1.a=10; // corresponds to the value of obj1
obj1.c='A'; // ....
and so on..
Okay,
Now this following code snippet I cannot understand.
Snippet 2:
struct node {
node* left;
node* right;
int value;
};
How can we define node* left and node* right in the structure named node when the structure node hasn't even been completely formed yet?
What does it even mean? How can it point to something that hasn't even been formed yet?
How does it even know the size of the object to allocate when we create an object of node?
Can anyone help me out on this?
Edit: The code in the question is not valid C code, but it is valid C++ code
How can we define node* left and node* rightin the structure named node when the structure node hasn't even completely formed yet?
node * is pointer and a pointer does not require complete definition. Only declaration of type is enough.
What does it even mean? How can it point to something that hasn't even been formed yet?
Such structures are known as self-referencing. They can refer to the an object which (must)have same type as they have. This is one of the basis of linked list, trees, graph and many data structure.
How does it even know the size of the object to allocate when we create an object of node?
As object contains pointer, size of pointer is fixed and is known before knowing the complete object. Hence, size of object can be allocated. In this case, it will be size of data members+size of pointers+some padding.
Adding to the previous answer.
First you need to understand this What is the difference between a definition and a declaration?
Self referencing is a feature programming languages offer. It gives the user (the programmer) flexibility in building data types (graphs, linked list and many more).
Self referencing is using the fact that pointers could be declared and only be defined later. It sounds a little far fetched for the beginner, but the reason that is that pointers have a fix size of 4 bytes. Therefore, the compiler already knows how much memory to allocate for it and it assumes the pointer will be declared later on.
Hope I made it clearer
So I've been tinkering around with object orientism in C by making a simple little stack using a 'class' struct and a typedef'd 'instance' struct. The class struct is simply full of function pointers that operate on pointers to instance structs. When I first went about it, I said to myself "I'll just bind the pointers when I initialize the instance struct!" You might guess that this didn't work, since my initialization function was actually a pointer that still had not been assigned a value yet.
(it's currently almost 5AM - closer to wakeup time than bedtime)
So, I am asking if there is any way to effectively bind the function pointers of the at runtime such that I don't need to explicitly call a function that binds them - I was thinking maybe some sort of counterpart to atexit.
If the 'class' struct is always the same, you can initialise it statically:
void do_x_to_instance(instance *);
struct class_type {
void (*do_x)(instance *);
...
} myclass = {
&do_x_to_instance,
...
};
This is how the Python C API works to define extension types, for example.