struct Employee {} compare struct {} Employee - c

I read a tutorial in which there is this struct:
struct
{
char Name[25];
int Age;
float SkillRating;
} Employee;
defines a new aggregate, called Employee, containing fields called Name (of type character), Age (of type integer), and SkillRating (of type float).
In contrast, the C statement:
struct EmployeeType
{
char Name[25];
int Age;
float SkillRating;
};
does not define a new aggregate variable, but defines a new aggregate type,
EmployeeType.
This new data type could then be used to declare variables in the
same way as a primitive data type. That is, in the same way that C allows the
variable x to be declared as an integer using the statement
I am confused here. Does the distinction exist if place 'Emplyee` on different position?
I guess they are identical.

In the first case, the struct is unnamed and Employee is a variable of that unnamed struct. You can directly modify it like this:
int main()
{
Employee.Age = 100;
return 0;
}
In the second case, EmployeeType is just a type, but you didn't make any instance of it yet. You can make any amount of instances:
int main()
{
struct EmployeeType a; // employee on the stack
a.Age = 100;
struct EmployeeType *b = malloc(sizeof(struct EmployeeType)); // employee on the heap
if (b) { // set the age of b if the allocation succeeded
b->Age = 100;
}
free(b); // malloc-allocated memory must be freed afterwards
return 0;
}
You can even do both at once:
struct EmployeeType
{
char Name[25];
int
Age;
float SkillRating;
} Employee;
Here, Employee is one instance of it, but you can make additional instances:
int main()
{
Employee.Age = 100;
struct EmployeeType a; // employee on the stack
a.Age = 100;
return 0;
}

struct A_s { int memb; }; // declares a struct A_s
struct A_s a; // declares a variable a of type struct A_s
now you can combine struct declaration with variable declaration:
// declares struct A_s and in the same line declares variable a
struct A_s { int memb; } a;
Now you can create an anonymous struct by omitting the structure tag name:
// declares anonymous struct and in the same line declares variable a
struct { int memb; } a;
Now structure declaration can be really put anywhere:
int func(int a, struct A_s { int memb; } b);
struct A_s { int memb; } func(int a);
struct B_s {
int memb1;
struct A_s {
int memb2;
} a;
};
I think the description of the C code of the field "name" in your post is invalid. The field name inside "aggregate" (read as: structure) has the type "array of 25 characters", not character type.

struct keyword in C can be used to declare aggregate datatypes, aggregate data objects or both.
In your first declaration (and definition), a tag name is missing, so an anonymous object 'Employee' is created. 'Employee' remains the only object of this struct. You cannot create more objects from this struct anywhere else in the code.
In your second declaration, you have created a struct type which can be instantiated many times (i.e., multiple instances of this struct can exist) as shown below -
struct EmployeeType employee_1;
struct EmployeeType employee_2;
Both these syntax are useful depending on the use case.

Related

typedef structure with * to the name in c

I've come across this strange way to define a structure in C and I cannot find anywhere what this really is?
typedef struct {
int val;
} *Name;
What is the difference to this?
typedef struct {
int val;
} Name;
I see however that I have to use "->" on the first and "." on the second, but what is really the difference?
In the first case
typedef struct {
int val;
} *Name;
the name Name is declared as an alias for the type pointer to an unnamed structure.
You can use this pointer type for example the following way
Name ptr = malloc( sizeof( *ptr ) );
and then you can write for example
ptr->val = 10;
or
( *ptr ).val = 10;
That is in this declaration there is declared the pointer ptr of the type Name and dynamically created an object of the structure and the pointer points to this dynamically created object.
In the second case
typedef struct {
int val;
} Name;
the name Name is declared as an alias for the unnamed structure itself.
To declare an object of this type you can just write
Name name;
and then
name.val = 10;
or just
Name name = { 10 };
and an object of the structure type will be created.
Or if you want to allocate an object of the structure type dynamically you can write
Name *ptr = malloc( sizeof( Name ) );
To make it more clear here are another examples of using typedef.
typedef int A[10];
this typedef declares the name A as an alias for the array type int[10].
you can write after that
A a;
This declaration declares array object a of the type A that is equivalent to int[10].
This declaration
typedef int ( *A )[10];
declares the name A as an alias to the type pointer to an array of type int[10].
This declaration can be used for example the following way
int a[10];
A ptr_a = &a;
When you write
typedef struct {
int val;
} Name;
you're saying "the name Name now refers to a struct with one element, an int named val."
When you write
typedef struct {
int val;
} *Name;
the star changes the meaning so that this says "the name Name now refers to a pointer to a struct with one member, an int named val." This is why you need to use the arrow operator rather than a dot: in the first case, Name is a type that's an honest-to-goodness structure, and in the second Name is a type that's a pointer to a structure.

Nested struct in C issue

I have a struct declaration in C that looks something like this:
static struct {
int a;
int b;
} myStruct[10];
I want to declare a struct member variable inside myStruct, so I try to add this:
static struct {
int c;
int d;
struct myStruct[10] s;
} myNestedStruct[100];
I'm getting a bunch of errors i.e. syntax error before or at: [ and
syntax requires ";" after last struct/union member. What would the better way to implement the nested structs be?
EDIT: My code now looks like this:
static struct {
int a;
int b;
} myStruct[10];
static struct {
int c;
int d;
struct myStruct s[10];
} myNestedStruct[100];
However I'm getting an error: incomplete struct/union/enum myStruct: s
You need to declare myStruct first before using it as a struct type.
struct myStruct {
int a;
int b;
};
static struct {
int c;
int d;
struct myStruct s[10];
} myNestedStruct[100];
This creates a variable called myNestedStruct which is an array of 100 structs, each containing two ints and an array of 10 mystructs.
When you write code like
struct { ... } Foo;, it's not declaring a type named Foo but a variable. Its type is an anonymous struct corresponding to what you put in the curly braces. If you want to declare a type, write struct Foo { ... };.
That's where your error is coming from -- myStruct is not a type name, so when you write struct myStruct in the definition of myNestedStruct the compiler thinks you're about to define a struct by that name. But then it encounters an [ which shouldn't be the next token in a struct declaration ever so it tells you can't make sense of the code.

What is the difference between these two ways of writing a structure?

struct one
{
int member;
};
struct two
{
int member;
} structure;
If I want to call the above structures in the main() function then in the first case do I need to name the struct one to any random name of my choice and then and then call its member like this:
int main() {
struct one random_name;
random_name.member = 1;
}
and in the second case I have already named the structure so it's just that I can directly call the member with the name structure like this:
int main() {
structure.member = 1;
}
Is the version below valid or do I have to put typedef in front of the struct?
struct {
int member;
} structure;
Using int as the type of the structure members throughout, then:
struct one
{
int member;
};
This is a perfectly fine definition of the type struct one. It defines no variables of type struct one; it is simply a type that can be used later in the translation unit.
struct two
{
int member;
} structure;
This is a perfectly fine definition of the type struct two and is also the definition of a variable structure of type struct two.
If I want to call the above structures in the main() function then in the first case do I need to name the struct one to any random name of my choice and then and then call its member like this:
int main(void)
{
struct one random_name;
random_name.member = 1;
}
If you want to use a variable of type struct one, you will have to define it, and the way you've done so is fine. You don't 'call' members of structures. You use them.
and in the second case I have already named the structure so it's just that I can directly call the member with the name structure like this:
int main(void)
{
structure.member = 1;
}
This is also valid because you defined the variable structure at the same time as you defined the type struct two.
Is the below version valid or do I have to put typedef in front of the struct:
struct
{
int member;
} structure;
This is also legitimate code. It defines an anonymous structure type and defines a single variable of that type. It is the only variable of that type that can exist, but occasionally it is useful to use this.
Note that if the last structure was followed by:
struct
{
int member;
} form;
the types of the variables form and structure are different; you cannot legitimately assign one to the other, for example, or pass either of them to another function, etc.
More typically, you either give the structure type a tag (struct three) or use a typedef (typedef struct { int member; } four;) or both (typedef struct five { int member; } five;, where it is legitimate to use the same name for the tag and the type name as I showed, though there is also an extensive tradition of using different names for the type and the tag).
So with typedef struct { int member; } structure;, in main() creating one or more variables of type structure is possible, like this?
structure first_var;
structure second_var;
This is entirely legitimate. You could instead write:
structure first_var, second_var;
though many people prefer one variable per declaration.
Whereas if we don't use typedef and just do struct { int member; }structure; then I have just got one variable with name structure and can use that only in main(), such as structure.member = 1; and can't create more.
More or less. You can write:
struct { int member; } var1, var2, … varN;
and now you have multiple variables all of the same type. However, although you can write:
struct { int member; } var1;
struct { int member; } var2;
the two variables var1 and var2 are not officially of the same type. There are complicated bits of wording in the standard in section 6.2.7 Compatible types and composite types which might let you off the hook, but GCC 4.9.1 set fussy says:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -c tagless.c
tagless.c: In function ‘main’:
tagless.c:13:10: error: incompatible types when assigning to type ‘struct <anonymous>’ from type ‘struct <anonymous>’
var1 = var2;
^
$
tagless.c
struct
{
int member;
} var1;
struct
{
int member;
} var2;
int main(void)
{
var1.member = 1;
var2.member = 2;
var1 = var2;
return 0;
}
two more doubts:::::::
Whereas if we don't use typedef and just do struct{int member;}structure;
then i just got one variable with name structure and can use that only in
main structure.member=1; and can't create more –
Ans : You can always create more than just one variable once you have declared the structure, so its not that if you dont use typedef you can have only one variable for your structure. For eg:
struct structure
{
int number;
};
int main()
{
structure var1, var2, var3; //...any number of variables can be declared here.
var1.number = 30;
var2.number = 45;
var3.number = 90;
printf("\nvar1 = %d, var2 = %d, var3 = %d\n", var1.number, var2.number, var3.number);
return 0;
}
For a better understanding of typedef,
Consider this example :
1.
struct structure
{
int number;
};
typedef struct structure structure;
2.
typedef struct structure
{
int number;
}structure;
---------------------
Both of the above declarations are equivalent.
typedef is used to define a new name for a variable or a keyword.
Suppose in case if your structure declaration is something like this :
struct this_is_my_structure
{
int number;
};
then every time you declare an instance of this structure you will have to use this long name in front of your instance, like:
int main()
{
struct this_is_my_structure var1; // you dont want to write such long types for variables
var1.number = 23;
return 0;
};
You will find typedef helpful here :
typedef struct this_is_my_structure structure;
Now every time you want to declare an instance of type "this_is_my_structure" all you have to do is the following :
int main()
{
structure var1;
var1.number = 23;
return 0;
}

Creating "nested structs" without -fms-extensions?

I have a struct with some properties:
struct a {
char* id;
int a;
int b;
int c;
}
I also have a struct with the same properties, but without the id.
struct b {
int a;
int b;
int c;
}
I know that C11 supports anonymous structs, so I could do something like this:
struct a {
char* id;
struct {
int a;
int b;
int c;
}
}
However, if I give the inner struct a tag, it fails. Is it possible to create nested structs like this without using a non-standard compiler option like -fms-extensions?
You can give the inner structure a name or a tag or both in C11 (i.e., without the use of any extension).
Without a tag and without a name, your inner structure is a C11 anonymous structure:
struct a {
char* id;
struct {
int a;
int b;
int c;
};
};
If you give the inner anonymous structure a name, it is no longer an anonymous structure. It is a regular C89/C99/C11 structure member and you cannot access the inner structure members directly as with anonymous structures.
If you give the inner anonymous structure a tag (but still no name), it is just a C89/C99/C11 structure declaration. There is no member added and the declaration of struct a is the same as:
struct a {
char* id;
};

C programming: Dereferencing pointer to incomplete type error

I have a struct defined as:
struct {
char name[32];
int size;
int start;
int popularity;
} stasher_file;
and an array of pointers to those structs:
struct stasher_file *files[TOTAL_STORAGE_SIZE];
In my code, I'm making a pointer to the struct and setting its members, and adding it to the array:
...
struct stasher_file *newFile;
strncpy(newFile->name, name, 32);
newFile->size = size;
newFile->start = first_free;
newFile->popularity = 0;
files[num_files] = newFile;
...
I'm getting the following error:
error: dereferencing pointer to incomplete type
whenever I try to access the members inside newFile. What am I doing wrong?
You haven't defined struct stasher_file by your first definition. What you have defined is an nameless struct type and a variable stasher_file of that type. Since there's no definition for such type as struct stasher_file in your code, the compiler complains about incomplete type.
In order to define struct stasher_file, you should have done it as follows
struct stasher_file {
char name[32];
int size;
int start;
int popularity;
};
Note where the stasher_file name is placed in the definition.
You are using the pointer newFile without allocating space for it.
struct stasher_file *newFile = malloc(sizeof(stasher_file));
Also you should put the struct name at the top. Where you specified stasher_file is to create an instance of that struct.
struct stasher_file {
char name[32];
int size;
int start;
int popularity;
};
How did you actually define the structure? If
struct {
char name[32];
int size;
int start;
int popularity;
} stasher_file;
is to be taken as type definition, it's missing a typedef. When written as above, you actually define a variable called stasher_file, whose type is some anonymous struct type.
Try
typedef struct { ... } stasher_file;
(or, as already mentioned by others):
struct stasher_file { ... };
The latter actually matches your use of the type. The first form would require that you remove the struct before variable declarations.
the case above is for a new project. I hit upon this error while editing a fork of a well established library.
the typedef was included in the file I was editing but the struct wasn't.
The end result being that I was attempting to edit the struct in the wrong place.
If you run into this in a similar way look for other places where the struct is edited and try it there.
The reason why you're getting that error is because you've declared your struct as:
struct {
char name[32];
int size;
int start;
int popularity;
} stasher_file;
This is not declaring a stasher_file type. This is declaring an anonymous struct type and is creating a global instance named stasher_file.
What you intended was:
struct stasher_file {
char name[32];
int size;
int start;
int popularity;
};
But note that while Brian R. Bondy's response wasn't correct about your error message, he's right that you're trying to write into the struct without having allocated space for it. If you want an array of pointers to struct stasher_file structures, you'll need to call malloc to allocate space for each one:
struct stasher_file *newFile = malloc(sizeof *newFile);
if (newFile == NULL) {
/* Failure handling goes here. */
}
strncpy(newFile->name, name, 32);
newFile->size = size;
...
(BTW, be careful when using strncpy; it's not guaranteed to NUL-terminate.)
The reason is you did not declare type struct stasher_file, you define a struct variable stasher_file
instead.
In C, the declaration of structure:
struct structure-tag {
member1
member2
...
};
structure-tag is an optional name following the keyword struct.
After declaration, you can define a variable:
struct structure-tag var1, *var2;
Also, you can do both declaration and definition like:
struct structure-tag {
member1
member2
...
} var1, *var2;
So in your case, you could try this:
struct stasher_file {
char name[32];
int size;
int start;
int popularity;
} *files[TOTAL_STORAGE_SIZE];
struct stasher_file *newFile = malloc(sizeof(struct stasher_file));
... other code ...
That's all.

Resources