placement of keyword struct in C [duplicate] - c

This question already has answers here:
Understanding typedef with struct [duplicate]
(6 answers)
Closed 5 years ago.
I have few questions connected with struct and typedef, there is piece of code and I have marked some places where I'm not sure if the syntax is correct. I use Eclipse editor and it shows me when there is problem in compilation. I just don't understand why is sometimes keyword struct needed and sometimes not. I may have also some mistakes of using this keyword. So plese help me to understand it.
let's have struct
typedef struct player
{
char *name;
int gameId;
int points;
int socketfd; //socket descriptor of player
int state;
} player_struct;
lets have another struct
#define PLAYERSLEN 2
typedef struct game{
struct player_struct *players[PLAYERSLEN]; //PLACE1
//some code
} game_struct;
let's have function
player_struct *create_player() //PLACE2
{
player_struct *player; //PLACE3
//alokace pameti
player = (player_struct *) malloc(sizeof(player_struct)); //PLACE4
//PLACE5
player->gameId = -1;
player->points = 0;
player->state = 0;
return player;
}
let's have function? In fact what does this definition mean?
void *( player_struct *player) //PLACE6
{
//some code
}
Questions references:
PLACE1 - is this correct? why can't I use just player_struct *players[PLAYERSLEN]; ??
PLACE2 - it looks like there is not needed struct before player_struct , is it correct? why?
PLACE3 - it looks like there is struct also not needed, is it correct? why?
PLACE4 - it looks like there is struct also not needed, is it correct? why?
PLACE4 & PLACE5 I may should handle errors there, cause there is malloc so I should probably put all the line with PLACE4 to if and if the malloc fails I should put at PLACE 5 free(player). Am I right?
PLACE6 what could have mean this function or whatever it is? The code inside brackets which is not included here should delete the player .. I just don't understand the syntax of wrote function - what does it mean?
PLACE6 - again similar as previous why is not necessary put the keyword struct before player_struct at this line? is it correct?
Really thanks you for your time.

You're doing two things in the initial definition:
You're defining the structure with the type name struct player.
You're creating a typedef called player_struct, which is just an alias for struct player.
As such, either struct player or player_struct is correct (and more-or-less equivalent), but struct player_struct refers to a completely separate type, and is probably incorrect unless you're trying to confuse people.
Now, handling your six cases in order:
PLACE1: As noted above, this code is actually wrong as it stands.
PLACE2, PLACE3, PLACE4: All correct; see above for an explanation.
PLACE5: Yes, you should probably check that player != NULL here just to be sure.
PLACE6: Again, this is correct, and the reason why is above. I'm not sure what void *(...) is supposed to be, though -- if * is actually a function name then it's probably fine though.

It's because the labels are in two separate namespaces (yes, even in C). There's a special namespace for structs.
I like to declare the label in both namespaces, using this:
typedef struct mon_struct {
int a;
} mon_struct;
then you can use either/both struct mon_struct mon = ... or just mon_struct mon = ....
Update
If you want to use just one label, then you can use one of the following:
struct mon_struct { int a; };
// requires namespace resolution using struct tag:
void f(struct mon_struct p);
// -= OR =-
// slightly awkward declaration
typedef struct { int a; } mon_struct;
// but the type exists in the global namespace,
// so we don't need to use the struct tag:
void f(mon_struct p);
but this becomes messy if you are using the struct in both C and C++, particularly when the declaration or implementations move between C and C++ translations without proper guarding (extern "C" { ...stuff... }).
so you might opt to declare it in both namespaces to minimise breakage:
typedef struct mon_struct { int a; } mon_struct;
void f(struct mon_struct p); // << ok
void f2(mon_struct p); // << ok

No. player_struct is a typedef for struct player. You don't need the struct keyword in this case.
Correct. You created a type definition called player_struct which means struct player.
Same reason as 2.
Same reason as 2 & 3.
Yes, you should check to see if malloc() returns NULL. In addition, don't cast the return value from malloc(). Doing so can hide #include errors.
That's not a valid function definition. You don't need struct because of the typedef - same as above.
You may find this all makes more sense if you remove the words typedef, player_struct, and game_struct from your code entirely. Then once you get used to how that all works, you can reintroduce the typedefs and maybe cut down on some typing. As a quick example, you can break down your first definition into its components:
struct player
{
char *name;
int gameId;
int points;
int socketfd; //socket descriptor of player
int state;
};
typedef struct player player_struct;
Maybe that will help you make sense of it?

You don't need struct in PLACE1... as long the definition of player_struct is known, ie, declared before it, or from a .h before it.

Related

Defining a new instance of a struct [duplicate]

This question already has answers here:
Is it optional to use struct keyword before declaring a structure object?
(3 answers)
Closed 2 years ago.
I tried typing the following code in a simple C project, but it keeps saying that MyStruct is undefined – unless I add struct before every MyStruct (i.e. struct MyStruct my_struct; which just feels wrong?).
struct MyStruct {
int my_int;
}
int main() {
MyStruct my_struct;
my_struct->my_int = 1;
return 0;
}
It’s not wrong, it’s the way C works. Type name is struct MyStruct (it would be simply MyStruct in C++). If you feel that inconvenient, make a typedef, like:
typedef struct MyStruct { ... } MyStruct;
That may or may not be considered a good practice, though.
Also note that a struct (but not a typedef) and a function can have the same name (without the struct prefix). sigaction is a real-word example of that.

How to capture a struct declaration in function

I have the following c code:
struct {
short s;
int n;
} variableName;
I want to write a function to capture this variable like so
void func(MyStruct* var){
//do stuff
}
func(&variableName);
I would like to do this without providing a definition for the struct. Is there a way to capture variableName?
No, you can't pass an "anonymous" struct into a function in C. You could of course define your function to accept the arguments individually:
void func(short s, int n) { ... }
Or you can define the MyStruct structure in a place that both the function and the calling code has visibility to. Note that the whole struct is passed by value (copy) when you do that, which may be the behavior you want here (or may not be).
You may be looking for something more like a "dictionary" or "associative array" or "hash" type that many other languages provide, with arbitrary key value pairs in it. Pure C does not have a facility for this; the compiler wants to know the layout of a structure in advance.
(I'm not sure if you might be asking about a slightly more esoteric idea, which is hiding the composition of a structure and passing around an "opaque handle" out of and into an API. There are ways to structure that in C, but please say so if that's what you're talking about.)
Completely overlooked "I would like to do this without providing a definition for the struct. Is there a way to capture variableName?" in the OP, unless it was edited after. The question makes less sense now, but heres how you could normally pass a struct to a function for future readers.
#include <stdio.h>
struct StructName{
short s;
int n;
};
void func(struct StructName struct_var){
printf("Param values are: %4X %4X\n", struct_var.s & 0xFFFF, struct_var.n & 0xFFFF);
}
int main(){
struct StructName struct_var;
struct_var.s = 0xDEAD;
struct_var.n = 0xBEEF;
func(struct_var);
}
//It looks like you are trying to use the definition as a variable. Here the definition is StructName and the variable is struct_var.
this sample code outputs:
Param values are: DEAD BEEF
If you use clang or gcc, you may be able to use typeof:
struct foo {
struct {
int i;
} anon;
} foo;
void do_something(typeof(foo.anon)* member) {
member->i = 1;
}
If there is no global instance of your type, you may be able to use typeof((struct foo){}.anon).
This comes with a lot of downsides. The most obvious ones are that:
it's not standard, and it ties you to clang/gcc
it's pretty darn ugly
it might not behave as you expect anyway
For instance, structurally-equivalent anonymous types do not have the same type, so in something like this:
struct foo {
struct {
int i;
} anon1;
struct {
int i;
} anon2;
} foo;
anon1 and anon2 both have a different type, meaning that typeof one of them cannot be used to refer to both.
In the long run, you will almost certainly find that it's worth naming the structures, especially if you use them as function arguments. For instance, if you want to make your variable available from a header, I think that you'll have to work pretty hard to keep it anonymous.
Although it's not particularly pretty and not compatible with C++, C puts the name of nested declarations in the global namespace, so this is portable and it's not a very big code change to front-load:
struct {
struct not_anon {
int i;
} anon;
} foo;
void do_something(struct not_anon* member) {
member->i = 1;
}

Using a struct inside a struct

How can I use struct A to modify the data inside a struct B. Which has no name, just a type.
struct A {
struct B;
};
struct B {
int data;
};
Since this is for school, I can't change the code above. I can only use it. I tried something like this for my main but it doesn't work
int main (){
struct A myStruct;
myStruct.B.data = 3;
return 0;
}
Thanks in advance.
Edit: Sorry I was just trying to post this as fast as possible that's why I didn't post this with proper c syntax. Anyway, it's my fault for not being clear enough on my question.
I'm aware that my main doesn't work I just want to know if it's ever possible to access the data inside struct B without declaring a name for it inside struct A as I have above. This is the code I was given by a teacher, so I didn't want to modify the structs because I thought maybe she wants us to brainstorm a way to use it the way she wrote it.
The way iharob explains it works perfectly by declaring struct B before struct A, and actually giving a name to struct B.
Is it simply not possible to access that data inside struct B without giving it a name?
The code you posted is not even c code, it would not compile.
Your main mistake is that you don't need to use the struct name to access the member. This should be good
struct B
{
int data;
};
struct A
{
struct B member;
};
int main(void)
{
struct A instance;
instance.member.data = 3;
return 0;
}
I assume that you posted some sample code, don't do that. Post the actual code that has issues. The code you posted is completely invalid because some one of the definitions lack the type, you can't declare structs without using struct in c except if you typedef it. So please post the actual code the next time.
And don't build such complicated structs with struct members unless you really know what you are doing.

Is this a coding convention?

I am doing feature enhancement on a piece of code, and here is what i saw in existing code. If there is a enum or struct declared, later there is always a typedef:
enum _Mode {
MODE1 = 0,
MODE2,
MODE3
};
typedef enum _Mode Mode;
Similary for structure:
struct _Slot {
void * mem1;
int mem2;
};
typedef struct _Slot Slot;
Can't the structures be directly declared as in enum? Why there is a typedef for something as minor as underscore? Is this a coding convention?
Kindly give good answers, because i need to add some code, and if this is a rule, i need to follow it.
Please help.
P.S: As an additional info, the source code is written in C, and Linux is the platform.
In C, to declare a varaible with a struct type you would have to use the following:
struct _Slot a;
The typedef allows you to make this look somewhat neater by essentially creating an alias. And allowing variable declaration like so:
Slot a;
In C there are separate "namespaces" for struct and typedef. Thus, without a typedef you would have to access Slot as struct _Slot, which is more typing. Compare:
struct Slot { ... };
struct Slot s;
struct Slot create_s() { ... }
void use_s(struct Slot s) { ... }
vs
typedef struct _Slot { ... } Slot;
Slot s;
Slot create_s() { ... }
void use_s(Slot s) { ... }
Also see http://en.wikipedia.org/wiki/Struct_(C_programming_language)#typedef for details, like possible namespace clash.
If the following is a structure:
struct _Slot {
void * mem1;
int mem2;
};
you need the following to declare a variable:
struct _Slot s;
Notice the extra struct before _Slot. It seems more natural to declare a variable like Slot s, isn't it?
If you want to get rid of extra struct, you need a typedef:
typedef struct _Slot Slot;
Slot s;
It's sort of code obfuscation technique which only make sense in small amount of cases.
People say it's more natural to not write "struct" and other subjective things.
But objectively, one at least a) can't forward declare such typedeffed struct, b) have to jump through one hoop when using ctags.

Why often a struct's tagName differs from the typedef's name?

Sometimes I see code like this (I hope I remember it correctly):
typedef struct st {
int a; char b;
} *stp;
While the usual pattern that I familiar with, is:
typedef struct st {
int a; char b;
} st;
So what's the advantage in the first code example?
You probably mean this:
typedef struct ST {
/* fields omitted */
} *STP;
The asterisk is at the end of the statement. This simply means "define the type STP to be a pointer to a struct of this type". The struct tag (ST) is not needed, it's only useful if you want to be able to refer to the struct type by itself, later on.
You could also have both, like so:
typedef struct {
/* fields omitted */
} ST, *STP;
This would make it possible to use ST to refer to the struct type itself, and STP for pointers to ST.
Personally I find it a very bad practice to include the asterisk in typedefs, since it tries to encode something (the fact that the type is a pointer) into the name of the type, when C already provides its own mechanism (the asterisk) to show this. It makes it very confusing and breaks the symmetry of the asterisk, which appears both in declaration and use of pointers.
It's a habit that stems from the time when typedef names and struct tagnames were in the same namespace. See http://blogs.msdn.com/oldnewthing/archive/2008/03/26/8336829.aspx
I think you are talking about :
typedef struct{
int a;
char b;
} object, *objectPointer;
This means that (new) type objectPointer is a pointer to struct (object) defined above. Its easy to declare pointers to object struct this way. For instance,
objectPointer A = (objectPointer)malloc(sizeof(object));
A->a = 2;
Now, A is a pointer to struct object and you can access its variables as described above.
In case, objectPointer was not defined,
struct object *A = (struct object *)malloc(sizeof(object));
A->a = 2;
So, I guess objectPointer is more intuitive and easy to use.
I hope that the first code would say a compiler error ,
I see no good reason for the typedef name be different from the tag name.
Now, the reason for which the tag name needs to be typedefed if you don't want to use
struct tag v;
but
tag v;
is probably an historical one. For as long as I remember, C had typedef but I don't know if it was true when struct have been introduced (handling of typedef is a nuisance in the C grammar). In the old code I've seen, using typedef for struct isn't done, and there are things like unix
struct stat;
int stat(const char*, struct stat*);
which would break with an automatic typedef. One those are introduced, changing is quite difficult (yes, C++ has automatic typedef but C++ has special wording to handle that case of overloading and it would be yet another complication).

Resources