Can i ask if the syntax for these two are the same? I keep getting confused because typedef construct have the struct name after the closing of the curly brace but for here it seems like the variable names are the ones defined after the closing of the curly brace.
struct{
int age;
float height;
}person1,*personPtr;
VS
struct person{
int age;
float height;
};
struct person person1;
struct person *personPtr;
In this declaration
struct{
int age;
float height;
}person1,*personPtr;
there are declared an unnamed structure an object of the structure type and a pointer to an object of the structure type.
You will be unable to refer the structure type in your program because it is unnamed.
These declarations
struct person{
int age;
float height;
};
struct person person1;
struct person *personPtr;
differ from the preceding declaration in the way as there is declared a named structure that can be referred in the program.
The code snippet would be equivalent if the first declaration will be rewritten like
struct person{
int age;
float height;
}person1,*personPtr;
Other answer addresses the question: "if the syntax for these two are the same?". Here, I will focus on the following statement:
"I keep getting confused because typedef construct have the struct name after the closing of the curly brace but for here it seems like
the variable names are the ones defined..."
So, although your post does not actually include a snippet showing a typedef struct {, I will include one here to help identify the differences between two cases, the unnamed struct and a typedef struct.
The difference between a typedef, for example...
typedef struct{
int age;
float height;
} person_s; //creates a new type "person_s"
person_s person1; //illustrates using new type to create an instance of the struct
...and one similar to your unnamed struct: (leaving off the pointer instance for simplification)
struct{
int age;
float height;
}person1;// create single instance of struct, but this instance
// cannot be used to create new instances
... is that the typedef version creates a new data type person_s. person_s can be used to create new instances of the struct anywhere in your code, within the scope in which it was created.
While the unnamed struct creates only one instance of the unnamed struct. And while the instance person1 can be used and referenced in several places of your code (limited only by the scope in which it was created.) but no new instances of the unnamed struct can be created beyond that initial instance person1.
So in summary,
person1 is a single instance of the unnamed struct and person_s is a brand new type. The new type can be used to create new instances of that variable like any other type. (eg int, float, ...), but no new instances of the unnamed struct can be created.
Can i ask if the syntax for these two are the same?
No, they are not.
The first version declares an anonymous struct (as it has no name) and two variables using that type,
The second version names the type, and then uses the type name to declare the variables.
I keep getting confused because typedef construct have the struct name
after the closing of the curly brace but for here it seems like the
variable names are the ones defined after the closing of the curly
brace.
Yes, variable declarations and typedef declarations are designed to be very similar, on purpose.
For example, int age; declares a variable called age. By adding a typedef before the declaration, as in typedef int age; we instead made age a type and not a variable. We can then use it to declare a variable
age my_age;
same as
int my_age;
And it works the same for structs
struct
{
int age;
float height;
} person;
declares a variable person, while
typedef struct
{
int age;
float height;
} person;
says that person is a type.
The design of making a typedef declaration look very similar to a variable declaration might have seemed like a good idea at the time, but perhaps it was not. More confusing than brilliant?
Related
I've the question about typedef statement.
Here is the code how i always write this statement:
typedef struct name
{
}name_t;
And here is the another example how i can write that:
typedef struct
{
}name;
Question is: what is purpose of that ways?
You need to use the first format if you have to refer to the type before the typedef is completed. This is necessary if the structure contains a pointer to the same type. This comes up when defining linked lists.
typedef struct name
{
int value;
struct name *next;
}name_t
You can't use name_t *next; inside the structure declaraction, because name_t isn't defined until later.
typedef struct name
{
}name_t;
name here is a struct tag and superfluous for the normal use-case, since you end up with a typedef anyhow and should only use name_t in your code from there on.
The only reason you'd add a tag there is the special case where you need a self-referencing struct such as a struct name* next; member in a linked list or such. In such cases we have to use the struct tag since the typedef name cannot be used before the typedef statement itself is done. Another alternative to that is to forward declare the struct.
The _t naming is industry standard way of naming types since the dawn of time. Unfortunately, the POSIX standard had the misguided idea to disallow such naming, so if you care about POSIX compliance, you should not name your types with _t in the end. If you don't care about POSIX, you should use _t because it gives proper, self-documenting code.
typedef struct name
{
int a;
double b;
char c;
}name_t;
name is a structure tag while name_t is a new type created by typedef.
To provide a structure tag explicitly is useful, if:
You want to implement a forward-declaration of the structure for use it in f.e. function definitions or other structures before the structure definition occurs (important if you have several translation units/C files).
For example:
File1.c
struct name; // forward declaration of structure `name`.
void foo(struct name *ptr)
{
....
}
struct bar
{
int x;
struct name y;
}
File2.c
typedef struct name
{
int a;
double b;
char c;
}name_t;
You want to define a pointer to an object of the structure itself inside of the structure, like required by linked lists:
typedef struct name
{
int a;
double b;
char c;
struct name *next;
}name_t;
Is the following, at file scope, a type declaration or an unnamed variable?
struct student_s {
char* name;
int age;
double height;
struct student_s* next;
};
If it is a type definition, then what is the difference with:
typedef struct student_s {
char* name;
int age;
double height;
struct student_s* next;
};
?
(Background: see my answer at Changing a variable from global to local - C, where I believe the first introduces an unnamed variable that is then optimized away by the compiler.)
Note: the question has been flagged as a possible duplicate of In what scope is a struct member identifier put? but I believe I am not asking a question about the scope of the members but about what the declarations actually create. However. answers to Difference between 'struct' and 'typedef struct' in C++? do explain my question.
As per the C standard, a structure declaration in the form like
struct student_s {
char* name;
int age;
double height;
struct student_s* next;
};
is the declaration of a type. Quoting C11, chapter §6.7.2.1
The presence of a struct-declaration-list in a struct-or-union-specifier declares a new type, within a translation unit. The struct-declaration-list is a sequence of declarations for the members of the structure or union. [...]
C standard does not mandate creating a variable (either named or unnamed) for that type.
In your second snippet, you actually (try to) typedef to nothing. However, if you change your snippet to the form of
typedef struct {
//.....members
} student_s ;
you'll be creating a type student_s (typedef to an unnamed structure type) which you can use later.
FWIW, we never talked about a variable being created here, anyways. It's all about types.
First declaration declares a type. After that declaration, the type struct student_s is known, and you can declare variables of that type or pointer to it :
struct student_s student1;
struct student_s *pStudent;
The second declaration is weird even if is compiles. The common usage would be :
typedef struct {
char* name;
int age;
double height;
struct student_s* next;
} studend_t;
which declares an alias student_t to an anonymous struct. It can then be used directly :
student_t student1;
student_t *pStudent;
BUT THE SECOND EXAMPLE DOES COMPILE (even with a warning) AND IS THE SAME AS FIRST ONE !
What it really does is to declare a void alias to struct student_s. The typedef is ignored and produces a warning : typedef requires a name, but as a side effect, the struct is declared, exactly as it was in first example.
So the true answer to the actual question is THERE ARE NO DIFFERENCES except for a warning.
Both are type definitions. The second one is one incomplete. It doesn't supply a name as the the argument of typedef. Much better is to use
typedef struct student_s {
char* name;
int age;
double height;
struct student_s* next;
} student;
Regarding the legality of
typedef struct student_s {
char* name;
int age;
double height;
struct student_s* next;
};
I've asked that as a separate question, Legality of `typedef struct foo {int bar};`
It's a type, and you can't have an anonymous instance of a struct. For comparison, this declares both the type struct_type and an instance struct_instance of that type:
struct struct_type {
/* blah */
} struct_instance;
If you wanted to declare another instance in isolation (from the type decl) you'd use
struct struct_type another_instance;
The use of typedef - if done correctly, unlike your example - just allows you to give the type another name which doesn't require the struct keyword to declare an instance:
typedef struct_type MyStruct;
MyStruct yet_another_instance;
or equivalently
typedef struct struct_type {
/* blah */
} MyStruct;
omitting the name (struct_type) gives you an anonymous struct type which can only referred to by its typedef'd name.
Note 1
Since your original struct contains a next pointer to its own type, that type must have a name at the point the member is declared. So, you cannot declare an anonymous struct with a self-typed pointer. If you give your anonymous struct type a name with typedef, that name doesn't exist until after the member declaration, so can't be used there.
typedef struct /*S*/ {
struct S *next; /* T doesn't exist yet, so without S, you can't declare this */
} T;
Note 2
You can declare an anonymous instance of an anonymous union, as a member:
struct S {
union {
int i;
unsigned u;
};
};
struct S s;
s.i = -1;
printf("%x\n", s.u);
but that's a very special case. I took the remark about this out of the main argument, in case it was misleading.
struct A { ... }
creates struct 'A' visible in struct namespace (which has nothing common with C++ namespaces). So, to access struct you have to use struct keyword;
struct A a;
When defined with typedef struct
typedef struct A { ... } B;
becomes visible and bound to B, and you can easily create struct like common variable of type B
B a;
Please, correct me someone, if I am wrong.
The difference is that with the first example, you have to declare a new variable like this: struct student_s variable;, however with the second example, you may simply do student_s variable;.
I am try to understand this C code:
typedef struct _IntElem *IntList;
typedef struct _IntElem { int head; IntList tail;} IntElem;
I understand that it defines a recursive type, a list. However I don't understand the way it is declared. What I understand is the second line, we define a structure named IntElem which consists of an integer and an IntList. But what is the _IntElem in this declaration?
The first line allocates memory for the list?
The first line
typedef struct _IntElem *IntList;
is to just create a typedef or an alias for struct _IntElem *. The alias is named IntList. FWIW, at this point of time, the definition of struct _IntElem need not to be known to the compiler.
The second line
typedef struct _IntElem { int head; IntList tail;} IntElem;
Actually defines an user-defined type _IntElem, with two members, head as int and tail as IntList(typedefed earlier)
typedef the type to IntElem.
Please Note: There is actually no variable created, for either of the type (s) (I'm not talking about the member variables, of course, they are part of the definition). So, there is no memory allocated , as such.
So, to be explicit
But what is the _IntElem in this declaration?
the _IntElem is the name of the user-defined data type. However, in some cases, it is optional. for example,
typedef struct { char name [32]; int age; float salary;} employee;
is both perfectly fine and legal, except the fact, in this case, we're creating an alias employee to an unnamed data type.
In C, if we have:
struct X
{
stuff....
};
then X is called a struct tag. It means that struct X is the name of a type. X on its own is not the name of a type. In fact X on its own behaves like any other undeclared identifier; this struct definition only defines the specific usage struct X.
We might say that struct tags live in a different namespace to other identifiers (not to be confused with C++ namespaces!)
Sometimes people don't like typing struct X everywhere. So they use typedef (which, confusingly, means to create a type alias) in order to make a single identifier that names the type:
typedef struct X SX;
means that SX is a type. But since struct tags are in their own namespace, you could even write:
typedef struct X X;
which means that X on its own refers to the same type as struct X does.
Hopefully you understand the code you are looking at now. I think it would have been clearer to write:
struct IntElem
{
int head;
struct IntElem *tail;
};
with the optional addition to save typing:
typedef struct IntElem IntElem;
Pointer typedefs are evil, so IntList can be omitted entirely. Possibly you could keep it around to use as an opaque type for the users of your list, but you should avoid using it during your list implementation.
As usual, Wikipedia's article on structs is less than clear. It gives the syntax for structs as this:
[typedef] struct [struct_name]
{
type attribute;
type attribute2;
/* ... */
[struct struct_name *struct_instance;]
} [struct_name_t] [struct_instance];
What would the typedef keyword do here?
What does the [struct_name] mean? (Is it the name you're giving to the new struct data type?)
What does the [struct_name_t] mean?
what does the [struct_instance] mean? (Is it creating a single instance of the struct?)
I presume [struct struct_name *struct_instance;] creates a pointer in the struct which would point to a second instance of the struct). Correct?
I would greatly appreciate an example: Say I have three files: main.c, sub.c and sub.h. I want to declare an instance of a struct in sub.h, and instantiate and use it it in sub.c. Say I want a Song type struct, with members char name[20] and char artist[10], and say I want to make an instance, mySong, {"Me singing", "Me"}, how would this look in sub.c and sub.h?
Thanks
•What would the typedef keyword do here?
It would allow you to create a typedef of your structre, just like any other type. This allow you to not have to type struct xxx struct_name everytime. You don't need this, hence the []
•What does the [struct_name] mean? (Is it the name you're giving to the new struct data type?)
Yes, if you chose too. You can also make a nameless struct so you don't need to give it a name.
•What does the [struct_name_t] mean?
That's the typedef'd name, if you chose to typedef the struct
•what does the [struct_instance] mean? (Is it creating a single instance of the struct?)
Yes, it's for creating one or more instance(s) of the sturct
•I presume [struct struct_name *struct_instance;] creates a pointer in the struct which would point to a second instance of the struct). Correct?
Right, this would be usefull for a "next" type pointer in a linked list.
struct example:
typedef struct foo{
int count;
struct foo *next;
} foo_t myfoo;
is an example of that filled in; this allows you to declare a new struct via:
foo_t new_foo_struct;
because of the typedef and typedef'd name. If you omit those like this:
struct foo{
int count;
struct foo *next;
} myfoo;
Now you'd have to use the struct key word for every instance, such as:
struct foo new_foo_struct;
to break it up over more than 1 file:
/*sub.h*/
typedef struct{
char name[20];
char artist[10];
}song;
Then in the source:
/*sub.c*/
#include "sub.h"
/*this needs to go into a function or something...*/
song mysong;
strcpy(mysong.name, "Mesinging");
strcpy(mysong.artist, "Me");
That article is just wrongly mixing different concepts, rectified this now. A struct is declared through
struct tagname {
... fields ...
};
that's just it, only that the tagname part is optional in some contexts.
In addition you may
declare an alias for the struct type through typedef
or a variable of the struct type
"in one go", but I don't think that it is good style and should be separated.
sub.h
------
typedef struct{
char name[20];
char artist[10];
}song;
sub.c
----
song mysong={"Me Singing","Me"};
typedef struct struct_name
{
char name[20];
char artist[10];
}struct_name_t structInstance;
typedef - this means that you are creating a new type (struct_name_t)
So, in C code you can create an instance like this:
struct_name_t myVariable;
or you can explicitly write:
struct struct_name myVariable;
The structInstance at the end means that you want to create an instance of your struct at the same moment you defined it (and the name of that variable is structInstance). It's not something you will use all the time, but it is useful in some situations.
If you want to create an instance of your struct and assign/initialize members at the creation time, you can do it like this:
struct_name_t myVariable = { "Foo", "bar" };
The 'name' member will contain "Foo" and the artist member will contain "bar".
Note:
If you write this:
struct_name_t myVariable = { 0 };
That will fill your entire struct with zeroes!
I was using my structure like this. I don't like to typedef as I have told it can hide errors.
However, I was looking at some sample code and I have seen structures declared like this. And this is the normal way I declare them.
struct person
{
int age;
char name[32];
};
using like this:
struct person person_a;
person_a.age = 20;
etc.
However, I have seen structures declared like this:
struct
{
int age;
char name[32];
}person;
and
struct _person
{
int age;
char name[32];
}person;
What is the difference between all these different techniques, and how would you decide when it is the best to use each particular one.
Many thanks for any suggestions,
This:
struct
{
int age;
char name[32];
}person;
declares a variable person that is a struct. The struct has no name, but you still use the person variable the same way.
struct _person
{
int age;
char name[32];
}person;
This is identical to:
struct _person
{
int age;
char name[32];
};
struct _person person;
It declares a struct named _person and then makes a variable called person of type struct _person.
In both the last two structures, you've allocated storage for the structure called person.
What I mean is if you have something like this:
struct person
{
int age;
char name[32];
};
It's just a declaration; no variable allocation is there and hence cannot be used inside the code. You can start using this structure after you have declared as follows:
struct person p1;
Then, p1 can be utilized p1.age or p1.name, etc.
In terms of real-world code, instead of
struct _person
{
int age;
char name[32];
}person;
we usually see
typedef struct _person
{
int age;
char name[32];
} person_t;
In this case, we can save typing and more importantly the structure behaves like any other built-in type such as int, etc.
For example,
person_t p1;
person_t *p1;
And, so on.
For the first case (of second example), you will use this approach if you are sure that you do need another object for this structure. This looks clean and is fast to code :)
For the second case you have a ready object named 'person' and an option to create an object later on as
struct _person object2
This is to explain why you will use either approach. The difference between them has been explained well above.
There's no magic there really,
struct person
{
int age;
char name[32];
} var;
is the same thing as:
struct person
{
int age;
char name[32];
};
struct person var;
The 1st code just creates the person struct.
The 2nd code creates an instance of the person struct called person_a.
The 3rd code creates an unnamed struct and an instance of it called person.
The 4th code creates a struct named _person and an instance of it named person.
If the purpose of the structure definition is to declare a logical data structure that has meaning outside of the local module, then you would expect to see the first construct in a header file.
In real world C code, structures are often declared for purley pragmatic reasons that are local in scope. For example, formatting data that will be copied into a buffer. In these cases it's very handy and logical to merge the structure type and variable declaration. Also, using an anoymous declaration for the structure type avoids cluttering the namespace with a name that is not needed.
I do have one critisim of these examples: in C, names with a leading underscore are considered to be reserved for compiler vendors by convention. So I don't think the last example is consistent with best practice.