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.
Related
Suppose we have a function pointer on a struct, which has the struct itself as the first argument, a typical callback scenario.
typedef void (*callback_type)(my_struct_type *mst, int whatever);
typedef struct {
// lots of fun stuff
callback_type notify_me;
} my_struct_type;
This produces a compiler error on the first typedef, as one might expect. error: unknown type name my_struct_type. Reversing the definitions produces the same result, but the unknown type is callback_type.
The easy solution is to do the following:
typedef struct my_struct_type_S {
// lots of fun stuff
void (*notify_me)(my_struct_type_S *mst, int whatever);
} my_struct_type;
However, doing this elides the function pointer type definition, which it would be nice to be able to easily refer to later, and use for static type checks, nice error messages, etc.
Any suggestions on how to resolve this?
Edit on "possible duplicate":
This scenario involves function pointer typedefs that are arcane to many people. I think this is a good example for that case, and additionally, the accepted answer is very clean, clear, and simple.
You can do this by giving the struct a tag and using a forward declaration of the struct. Then you can use the typedef for the function pointer, and subsequently complete the definition of the struct.
typedef struct my_struct_type_S my_struct_type;
typedef void (*callback_type)(my_struct_type *mst, int whatever);
struct my_struct_type_S {
// lots of fun stuff
callback_type notify_me;
};
You need to define the tag of the struct
typedef void (*callback_type)(struct _my_struct_type *mst, int whatever);
typedef struct _my_struct_type {
// lots of fun stuff
callback_type notify_me;
} my_struct_type;
I'm trying to forward declare struct_A and use it within struct_B not as a pointer but as a structure.
Within struct_B, I make reference to struct_B.
I can't seem to get it right - help?
Here's my code:
struct type_A_t;
typedef struct type_A_t type_A_t;
typedef struct type_B_t {
type_A_t a;
};
struct type_A_t{
void (*cb)(type_B_t *b1);
void (*cb)(type_B_t *b2);
};
The error I get is:
error: field 'type_A_t' has incomplete type
You can't do that. But in your example, since type_A_t only needs to know about pointers to type_B_t, why not switch it around like this?
typedef struct type_B_t type_B_t;
typedef struct type_A_t type_A_t;
struct type_A_t {
void(*cb)(type_B_t *b1);
void(*cb)(type_B_t *b2);
};
typedef struct type_B_t {
type_A_t a;
};
That is not possible. To use a type as a member, the type's size must be known, so it must be fully defined. Otherwise, sizeof(struct type_B_t) would be unknown after its definition, which makes no sense.
I can't seem to get it right - help?
Because it cannot be done.
The compiler doesn't know the size of that struct.
A forward declaration is enough for pointers though:
typedef struct type_B_t {
type_A_t a; // error
type_A_t* a; // OK
};
Of course, if in your real code, you can switch the order, as #Blaze's answer mention, then do that.
I remember my professor showed us how to replace a "struct" statement such as struct *pointerexample so that we do not have to type it out each time. However, I don't remember if they used a preprocessor directive such as #define or how they did it. Any ideas? Also, how would I do #define EXAMPLE struct *pointerexample? Is that the correct way?
Use a typedef:
struct pointerexample {};
typedef struct pointerexample *ppe;
With this, you can use ppe to create pointers to pointerexample:
ppe var1, var2;
A common approach is to first use a typedef to reduce the amount of typing when declaring a struct. This allows you to just use a named type rather than having to use the struct keyword everywhere. eg:
typedef struct myStruct {
int a;
char c;
} myStruct_t;
myStruct_t aStruct; // Declare a struct
aStruct.a = 0; // Set a to zero
myStruct_t* pS = &aStruct; // Pointer to a struct
pS->a=1; // Set a to one
typedef struct pointerexample SPE, * PSPE;
Now you can use SPE instead of the longish name. And better do not use PSPE as a pointer to the latter, as this is close to obsfucating code, in my opinion.
Using the pre-processor would do also:
#define SPE struct pointerexample
However this latter approach could lead to unexpected results under certain conditions. There is no need to use the pre-processor here, as there is the former solution.
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.
I am using structs in my project in this way:
typedef struct
{
int str1_val1;
int str1_val2;
} struct1;
and
typedef struct
{
int str2_val1;
int str2_val2;
struct1* str2_val3;
} struct2;
Is it possible that I hack this definition in a way, that I would use only types with my code, like
struct2* a;
a = (struct2*) malloc(sizeof(struct2));
without using keyword struct?
Yes, as follows:
struct _struct1
{
...
};
typedef struct _struct1 struct1;
struct _struct2
{
...
};
typedef struct _struct2 struct2;
...
struct2 *a;
a = (struct2*)malloc(sizeof(struct2));
Yes, you can use the typedef'ed symbol without needing the struct keyword. The compiler simply uses that name as an alias for the structure you defined earlier.
One note on your example, malloc returns a pointer to memory. Hence your statement should read
a = (struct2 *)malloc(sizeof(struct2));
Just to share, I've seen this approach, and though I personally don't like it (I like everything named and tagged =P and I don't like using variable names in malloc), someone may.
typedef struct {
...
} *some_t;
int main() {
some_t var = (some_t) malloc(sizeof(*var));
}
as a footnote. If you code in C++ then you don't need to do the typedef; a struct is a type automatically.