This video is great for hobby coders like me who are looking for immediate guidance. It incorporates various C features, but beginners should not be intimidated by the code. Although CodeVault describes it as using simple data types, it's important to note that he possesses deep knowledge of C. You will gradually become accustomed to reading and understanding such code, but it requires regular practice on a daily basis.
i tried to use this concept in my code and it made everything so much complicated, at first i was like "this is so cool" but after a while i realized i added so much complexity it became very hard to read and use functions
Making something like this typesafe would probably require either actual RTTI (and there's no RTTI in standard C) or some macro magic to make it generic. C is cool and all but without templates it might be better to write data structures for specific use cases. Anyway thanks for your videos :)
I think since enums take value and since stack_create function is type safe function, we should remove those if statements in stack_create function and add every possible data type size as value to enums. This way there is no need to add if statements and It is safe to use and there is no need to edit function, just for adding new data type. we could also use sizeof operator to get size of complex objects and store those as enum. type enum DataType { INT = 4, FLOAT = sizeof(float), ... } DataType; Please tell me if I am wrong.
That is correct. In this exact example, if you need just the size, this is the way to go. I wanted to make it more general since, with generic types, you might need to store more than just that number.
Yeah, I agree, in this example it could be done. Although this usually limits you to just passing the size whereas you might want to pass more information when dealing with generic types (in general, not just for the stack). Also, it's very clear from the get go what values the initialization function can take which, in a large enough project, helps a lot.
what about function pointers in a generic ADT that's pretty important, functions that the user creates and can use them with our function pointers that we made in the source file, it's complicated I think you should make a video about it. an ADT should be a header file and a source file right? so pretty much in the header file we write: typedef struct _stack *Stack; also "typedef void* Element" instead of typing void* everytime.(you can name it anything you want other than Element). in the source file the structure will look like this: struct stack { size_t size; ...... }
Definitely I'll take a look at this concept. I don't want to touch too many aspects of OOP in C, but, at some point in the future, I will provide some OOP lessons and surely I'll get to this topic as well
Stack s = { .type = type }; Is equivalent to: Stack s; s.type = type; I just find it easier to read this way. That dot is simply in the syntax and denotes that "type" is a member of the "Stack" struct.
Hello. In this case we are stuck with the types defined above. If we want in our application to define other types of data (with structs) would we have to refactor all the code?
Yes, the DataType enum holds information about what types can be stored in that stack. You can add as many values in that enum but you'll have to make sure you check for it when you do any operations with the Stack. So yes, you will have to refactor every time you add a new datatype. It isn't quite like in object oriented languages... It may be possible to do this using macros (or maybe even with more advanced functions) but it won't be easy.
@@CodeVault Would a better way be to pass the size of the data type you are going to have the Stack store? For instance, stackCreate(size_t size, size_t dataSize){//}. Instead of an if-else chain, the sizeof(type) would be passed as the dataSize parameter, and the effectiveSize would be equal to size * dataSize. Would this work? I am not experienced in C, but this is how I would probably approach it.
The Stack struct I have in the video is supposed to be like an array with some extra capabilities. Namely, that you have instant access to the last inserted element (first in last out). The type is of void* so that you can store any type of data to it there and the whole array is under void* data.
This video is great for hobby coders like me who are looking for immediate guidance. It incorporates various C features, but beginners should not be intimidated by the code. Although CodeVault describes it as using simple data types, it's important to note that he possesses deep knowledge of C. You will gradually become accustomed to reading and understanding such code, but it requires regular practice on a daily basis.
i tried to use this concept in my code and it made everything so much complicated, at first i was like "this is so cool" but after a while i realized i added so much complexity it became very hard to read and use functions
I agree. It should be used sparingly, not for everything. Similar to generics in other languages, you don't need to make everything generic.
@@CodeVault yep, lesson learned, trying to make everything generic is just asking for trouble
Making something like this typesafe would probably require either actual RTTI (and there's no RTTI in standard C) or some macro magic to make it generic. C is cool and all but without templates it might be better to write data structures for specific use cases. Anyway thanks for your videos :)
C23 has something close, you can do:
#define Stack(T) struct Stack_##T { T *data; size_t cap; size_t len; };
@@hwstar9416Also constexpr and two's complement ints ^^
I think since enums take value and since stack_create function is type safe function, we should remove those if statements in stack_create function and add every possible data type size as value to enums. This way there is no need to add if statements and It is safe to use and there is no need to edit function, just for adding new data type. we could also use sizeof operator to get size of complex objects and store those as enum.
type enum DataType {
INT = 4,
FLOAT = sizeof(float),
...
} DataType;
Please tell me if I am wrong.
That is correct. In this exact example, if you need just the size, this is the way to go. I wanted to make it more general since, with generic types, you might need to store more than just that number.
I think this is the first time he I've seen someone use C99 style structure declarations!!
Why not just go all in and pass the size in bytes of the data type you want to store, instead of a limited enum, to the initialization function?
Yeah, I agree, in this example it could be done. Although this usually limits you to just passing the size whereas you might want to pass more information when dealing with generic types (in general, not just for the stack). Also, it's very clear from the get go what values the initialization function can take which, in a large enough project, helps a lot.
@@CodeVault Understood. Now I realize like most things in programming, this solution has its strengths and weaknesses. Thank you.
How do you have this deep knowledge of c programming. Do you use any resources to learn. If yes pls state them.
The Linux or the C documentation. I have a fairly basic knowledge of C compared to others that worked professionally in the field for years
what about function pointers in a generic ADT that's pretty important,
functions that the user creates and can use them with our function pointers that we made in the source file, it's complicated I think you should make a video about it.
an ADT should be a header file and a source file right?
so pretty much in the header file we write:
typedef struct _stack *Stack;
also "typedef void* Element" instead of typing void* everytime.(you can name it anything you want other than Element).
in the source file the structure will look like this:
struct stack
{
size_t size;
......
}
Definitely I'll take a look at this concept. I don't want to touch too many aspects of OOP in C, but, at some point in the future, I will provide some OOP lessons and surely I'll get to this topic as well
Bad way
What do you think is a better way of creating generic data types?
i like this video
why you are using this dot in 4:56, could you explain this a little bit, a see this a lot but i do not know what is the reason behid this, thank you
Stack s = {
.type = type
};
Is equivalent to:
Stack s;
s.type = type;
I just find it easier to read this way. That dot is simply in the syntax and denotes that "type" is a member of the "Stack" struct.
@@CodeVault How would you do this for void** data?
@@CodeVault Stack s = {
type,
etc...
};
no need to write .type = type
Hello. In this case we are stuck with the types defined above. If we want in our application to define other types of data (with structs) would we have to refactor all the code?
Yes, the DataType enum holds information about what types can be stored in that stack. You can add as many values in that enum but you'll have to make sure you check for it when you do any operations with the Stack. So yes, you will have to refactor every time you add a new datatype. It isn't quite like in object oriented languages...
It may be possible to do this using macros (or maybe even with more advanced functions) but it won't be easy.
@@CodeVault Would a better way be to pass the size of the data type you are going to have the Stack store? For instance, stackCreate(size_t size, size_t dataSize){//}. Instead of an if-else chain, the sizeof(type) would be passed as the dataSize parameter, and the effectiveSize would be equal to size * dataSize. Would this work? I am not experienced in C, but this is how I would probably approach it.
what does s.top doing?
It's the top element of the stack
I can't understand how is it working. In linkedin there is a struct node pointer pointing to other node. How is it working here
The Stack struct I have in the video is supposed to be like an array with some extra capabilities. Namely, that you have instant access to the last inserted element (first in last out). The type is of void* so that you can store any type of data to it there and the whole array is under void* data.
😍
Hmm, I prefer C macros