Typedef struct question - c

Why would I want to do this?
typedef struct Frame_s
{
int x;
int y;
int z;
} Frame_t;
Also if I want to create an object what do I use Frame_s or Frame_t?

You would use Frame_t.
With typedef you are saying that Frame_t and struct Frame_s are the exact same type.
So these are equivalent sentences:
// 1
Frame_t f;
// 2
struct Frame_s f;
I would use:
typedef struct
{
int x;
int y;
int z;
} Frame_t;
And always declare my vars like this:
Frame_t f1, f2, f3;
Confusion usually comes from places where you use that sentence in a C++ piece of code. If you use C++ with that typedef you can use either:
// 1
Frame_t f;
// 2
Frame_s f;
But if you use a plain C compiler, then //2 is invalid.

Either you use struct Frame_s, or you use Frame_t.
Usually you do such a typedef so that you can use the typedefed name, Frame_t, and don't have to write struct whenever you refer to the type.
Aside from Frame_t being shorter than struct Frame_s there is no real difference.

Another aspect of typedef that has not yet been mentioned in the other replies is that it reserves the identifier and thus may avoid confusion. If you do a forward declaration like that
typedef struct Frame Frame;
you would avoid that some code that may use the same name Frame e.g a variable or function.
One very bad traditional example that comes in mind for this is "sys/stat.h" in POSIX: it defines a struct stat and a function stat:
int stat(const char *path, struct stat *buf);

To declare a value of the struct, you could use either struct Frame_s foo or Frame_t foo (the latter is more normal, since that's the whole point of typedefing). My guess is that Frame_s is meant to indicate the struct type itself, while Frame_t is the plain type that's normally used for Frame values.

typedef is used as a short form. So when a function which returns a structure of this type, normally you write -
struct Frame_s *function_name()
The code start to get obfuscated. Function definitions become long etc. With this typedef you get -
Frame_t *function_name()
Clean code! Makes a big difference in maintenance...

So these two declarations are equivalent:
struct Frame_s f;
Frame_t f;
In fact, you could now leave Frame_s out of the declaration as it isn't needed.
typedef struct
{
int x;
int y;
int z;
} Frame_t;

Related

Header file typedef definition

Hi I was triying to make something like this, but I cant sort it out. The problem is one typedef needs the other one. I would really appreciate someones help!
#ifndef SHELL_DATA_H
#define SHELL_DATA_H
#include <buffer.h>
#define COMMANDS 10
#define MAX_ARGS 4
typedef struct {
void (*command)(int, char **, t_shellData *shelldData);
char *name;
char *description;
} t_command;
typedef struct {
t_command commands[COMMANDS];
t_buffer buffer;
char username[BUFFER_SIZE];
} t_shellData;
#endif
typedef struct command t_command;
typedef struct shelldata t_shellData;
struct command {
void (*command)(int, char **, t_shellData *shelldData);
char *name;
char *description;
};
struct shelldata {
t_command commands[COMMANDS];
t_buffer buffer;
char username[BUFFER_SIZE];
};
should fix it up for you. The structure tag and typedef name can be the same; I just renamed them for clarity.
C is a simple language, with an underlying principle of do not surprise people. For this reason, entities in C need to be declared or defined before they are used. As a simple example:
int f() {
int a = 7;
int b = a;
....
}
is OK, but this is not:
int f() {
int b = a;
int a = 7;
....
}
and while not exactly, languages like golang permit this -- the compiler will root around and find the definition you obviously wanted.
Typedef, in C, really just puts an entry into the symbol table; it is like a define, but less blunt, so the line:
typedef struct a A;
Serves to inform the compiler of two things: somewhere there is a structure with tag a, and I want A to be a shortform for it. There is another form of this:
struct a;
typedef struct a A;
Here, the first line tells the compiler "I want you to know about a thing called struct a"; and the second line "I want an alias to that struct a thing called A".
So, as the compiler progresses through the source, it knows that an A means a struct a, and even if it hasn't seen the definition of struct a, it has a placeholder.
But, if you attempted, before defining struct a to define another structure:
struct b {
struct a stuff;
int morestuff;
};
The compiler would complain, because it doesn't know the layout of a struct a; however this:
struct b {
struct a *stuff;
int morestuff;
};
is OK, because it knows how big a pointer is, and can defer its understanding of a struct a until it needs it.
So, Summary: declare or define data types before you attempt to use them. The C compiler requires it. A declaration is ok, unless you need the actual layout of it, in which case a definition is required.
Good Luck.

Dynamic array stack struct C

I have a couple of questions. I have a bit of a hard time understanding this code. What exactly is it doing?
For example:
What does typedef struct dynArrStruct do and why does it have dynArr at the end of it? I know the definition of typedef as "allows to created alias for a known data type" but that is jargon to me. Can someone try to put it in layman terms? Thank you!
Why are there 2 struct variables (a1/a2)?
Link to full code if needed:
http://www.cs.uic.edu/pub/CS211/CS211LectureNotesS13/dynArr.c
typedef struct dynArrStruct
{
double *location;
int length;
int currSize;
} dynArr;
int main (int argc, char**argv)
{
struct dynArrStruct a1;
dynArr a2;
int i;
//rest of code
}
What does typedef struct dynArrStruct do and why does it have dynArr at the end of it?
The typedef creates an alias to a type to save you some typing, or to improve readability. In this particular case, it creates an alias called dynArr for the struct dynArrStruct.
Without a typedef, i.e. with only this
struct dynArrStruct
{
double *location;
int length;
int currSize;
};
you would be forced to write struct dynArrStruct every time you need to declare a variable of that struct's type. With a typedef in place, you can write simply dynArr, and the compiler will interpret it as the struct dynArrStruct for you.
typedef struct dynArrStruct
{
double *location;
int length;
int currSize;
} dynArr;
Is a short form of two different pieces of code.
// define a struct by name dynArrStruct
struct dynArrStruct
{
double *location;
int length;
int currSize;
};
//Example of use
struct dynArrStruct d1;
and
// define an alias to "struct dynArrStruct" called dynArr
typedef struct dynArrStruct dynArr;
//Example of use
dynArr d2; //whoa so short!
In addition to dasblinkenlight's answer,
Why are there 2 struct variables (a1/a2)?
The code presented appears to be an example of poorly modularised code (a1) and well modularised code (a2). The modifications made to a1 are very similar to the modifications made to a2. However, the modifications made to a2 are abstracted out into functions (lines 53-55 correspond to the lines found in init, 57-58 correspond to the lines found in push and push), so that that functionality can be easily reused. An example of this reuse is lines 69-72.

What's the syntactically proper way to declare a C struct?

I've seen C structs declared several different ways before. Why is that and what, if anything, does each do different?
For example:
struct foo {
short a;
int b;
float c;
};
typedef struct {
short d;
int e;
float f;
} bar;
typedef struct _baz {
short a;
int b;
float c;
} baz;
int main (int argc, char const *argv[])
{
struct foo a;
bar b;
baz c;
return 0;
}
Well, the obvious difference is demonstrated in your main:
struct foo a;
bar b;
baz c;
The first declaration is of an un-typedefed struct and needs the struct keyword to use. The second is of a typedefed anonymous struct, and so we use the typedef name. The third combines both the first and the second: your example uses baz (which is conveniently short) but could just as easily use struct _baz to the same effect.
Update: larsmans' answer mentions a more common case where you have to use at least struct x { } to make a linked list. The second case wouldn't be possible here (unless you abandon sanity and use a void * instead) because the struct is anonymous, and the typedef doesn't happen until the struct is defined, giving you no way to make a (type-safe) pointer to the struct type itself. The first version works fine for this use, but the third is generally preferred in my experience. Give him some rep for that.
A more subtle difference is in namespace placement. In C, struct tags are placed in a separate namespace from other names, but typedef names aren't. So the following is legal:
struct test {
// contents
};
struct test *test() {
// contents
}
But the following is not, because it would be ambiguous what the name test is:
typedef struct {
// contents
} test;
test *test() {
// contents
}
typedef makes the name shorter (always a plus), but it puts it in the same namespace as your variables and functions. Usually this isn't an issue, but it is a subtle difference beyond the simple shortening.
It's largely a matter of personal preference. I like to give new types a name starting with a capital letter and omit the struct, so I usually write typedef struct { ... } Foo. That means I cannot then write struct Foo.
The exception is when a struct contains a pointer to its own type, e.g.
typedef struct Node {
// ...
struct Node *next;
} Node;
In this case you need to also declare the struct Node type, since the typedef is not in scope within the struct definition. Note that both names may be the same (I'm not sure where the underscore convention originated, but I guess older C compilers couldn't handle typedef struct X X;).
All your uses are syntactically correct. I prefer the following usage
/* forward declare all structs and typedefs */
typedef struct foo foo;
.
.
/* declare the struct itself */
struct foo {
short a;
int b;
foo* next;
};
Observe that this easily allows to use the typedef already inside the declaration of the struct itself, and that even for struct that reference each other mutually.
The confusion comes about because some of the declarations are in fact declaring up to three C constructs. You need to keep in mind the difference between:
A typedef declaration,
A struct definition, and
A struct declaration.
They are all very different C constructs. They all do different things; but you can combine them into the one compound construct, if you want to.
Let's look at each declaration in turn.
struct foo {
short a;
int b;
float c;
};
Here we are using the most basic struct definition syntax. We are defining a C type and give it the name foo in the tag namespace. It can later be used to declare variables of that type using the following syntax:
struct foo myFoo; // Declare a struct variable of type foo.
This next declaration gives the type another name (alias) in the global namespace. Let's break it down into its components using the previous basic declaration.
typedef foo bar; // Declare bar as a variable type, the alias of foo.
bar myBar; // No need for the "struct" keyword
Now just replace "foo" with the the struct's definition and voila!
typedef struct {
short d;
int e;
float f;
} bar;
typedef struct _baz {
short a;
int b;
float c;
} baz;
The above syntax is equivalent to the following sequence of declarations.
struct _baz {
short a;
int b;
float c;
}
typedef _baz baz; // Declare baz as an alias for _baz.
baz myBaz; // Is the same as: struct _baz myBaz;

What's the benefit of a typedef in C?

typedef struct _VIDEO_STREAM_CONFIG_CAPS
{
GUID guid;
ULONG VideoStandard;
SIZE InputSize;
SIZE MinCroppingSize;
SIZE MaxCroppingSize;
int CropGranularityX;
int CropGranularityY;
int CropAlignX;
int CropAlignY;
SIZE MinOutputSize;
SIZE MaxOutputSize;
int OutputGranularityX;
int OutputGranularityY;
int StretchTapsX;
int StretchTapsY;
int ShrinkTapsX;
int ShrinkTapsY;
LONGLONG MinFrameInterval;
LONGLONG MaxFrameInterval;
LONG MinBitsPerSecond;
LONG MaxBitsPerSecond;
} VIDEO_STREAM_CONFIG_CAPS;
Why not define structure VIDEO_STREAM_CONFIG_CAPS directly instead of involving _VIDEO_STREAM_CONFIG_CAPS?
Quite simply (at least for me) because some people like to be able to treat user defined types as "primary" types.
Just like I wouldn't like to have to say:
struct int i;
I prefer:
VIDEO_STREAM_CONFIG_CAPS vscc;
to:
struct VIDEO_STREAM_CONFIG_CAPS vscc;
In fact, I usually get rid of the structure tag altogether, preferring:
typedef struct {
GUID guid;
ULONG VideoStandard;
:
} VIDEO_STREAM_CONFIG_CAPS;
The only time I genarally use the tag is if I have to refer to the type within the type definition itself, such as in linked lists:
typedef struct sNode {
char paylod[128];
struct sNode *next;
} tNode;
That's because, at the time of creating the definition, tNode doesn't yet exist but struct sNode does (you can think of it as a simple sequencing thing if that makes it easier - struct sNode gets created on line 1 above, tNode on line 4, which means on line 3 where you create the next pointer, you have to use the structure name).
In the case you cite, the structure tag is superfluous at least in the code shown. Whether some other piece of the code declares a variable with the structure name rather than the typedef name is unclear.
In c, you have to put struct in front of a declaration of a struct type. Without this typedef, you'd have to write struct VIDEO_STREAM_CONFIG_CAPS each time you wanted to use it. With the typedef, you can say just VIDEO_STREAM_CONFIG_CAPS as you would in c++.
struct a {};
struct a A;
OR
typedef struct a {} a;
a A;
In that case, each time a variable of type VIDEO_STREAM_CONFIG_CAPS is declared, the following syntax would be required:
struct VIDEO_STREAM_CONFIG_CAPS vscc;
With typedef struct it is:
VIDEO_STREAM_CONFIG_CAPS vscc;

C: pointer to struct in the struct definition

How can I have a pointer to the next struct in the definition of this struct:
typedef struct A {
int a;
int b;
A* next;
} A;
this is how I first wrote it but it does not work.
You can define the typedef and forward declare the struct first in one statement, and then define the struct in a subsequent definition.
typedef struct A A;
struct A
{
int a;
int b;
A* next;
};
Edit: As others have mentioned, without the forward declaration the struct name is still valid inside the struct definition (i.e. you can used struct A), but the typedef is not available until after the typedef definition is complete (so using just A wouldn't be valid). This may not matter too much with just one pointer member, but if you have a complex data structure with lots of self-type pointers, may be less wieldy.
In addition to the first answer, without a typedef and forward declaration, this should be fine too.
struct A
{
int a;
int b;
struct A *next;
};
You are missing the struct before the A*
typedef struct A {
int a;
int b;
struct A* next;
} A;
You can go without forward declaration:
struct A {
int a;
int b;
struct A *next;
};
Please, you're in C, not C++.
If you really must typedef a struct (and most programmers that I work with would not¹), do this:
typedef struct _A {
int a;
int b;
struct _A *next;
} A;
to clearly differentiate between _A (in the struct namespace) and A (in the type namespace).
¹typedef hides the size and storage of the type it points to ― the argument (and I agree) is that in a low-level language like C, trying to hide anything is harmful and counterproductive. Get used to typing struct A whenever you mean struct A.
typedef struct {
values
} NAME;
This is shorter way to typedef a struct i think its the easiest notation, just don't put the name infront but behind.
you can then call it like
NAME n;
NAME *n; // if you'd like a ptr to it.
Anything wrong with this approach?

Resources