2

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.

user1097772
  • 3,499
  • 15
  • 59
  • 95

4 Answers4

2

You're doing two things in the initial definition:

  1. You're defining the structure with the type name struct player.
  2. 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.
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
1

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
justin
  • 104,054
  • 14
  • 179
  • 226
  • Sorry, maybe I'm not right but I thought this is incorrect. But it may different case. Somebody told me that I must have different names there - but it was related to linked list ... – user1097772 Jan 26 '12 at 01:20
  • there's no C or C++ language restriction for the form `typedef struct NAME { ... } NAME;`. it is compliant and used widely. or have i misunderstood you? – justin Jan 26 '12 at 01:26
  • Usually from some reason I don't now exaclty why somebody in school said me that the name before { should be different than the name after } but it looks like it's not necesary. I looked at some tutorial and there they wrote that one is name of structure and one si name of type, they usually use different names but they don't say it could't be same. I have just never seen it same before, so I'm suprised it's possible.. – user1097772 Jan 26 '12 at 01:42
  • it's certainly possible. again, they're in separate namespaces. http://www.spinellis.gr/cscout/doc/name.html – justin Jan 26 '12 at 02:43
  • Thanks it's little more clear now. I have one more question: the mon_struct is used twice there, so can I get rid of one of them or is necesary to have them both and have them same (in this case)? – user1097772 Jan 26 '12 at 03:11
  • @user1097772 updated answer to clarify the usage. – justin Jan 26 '12 at 03:33
0

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.

Keith Nicholas
  • 43,549
  • 15
  • 93
  • 156
0
  1. No. player_struct is a typedef for struct player. You don't need the struct keyword in this case.
  2. Correct. You created a type definition called player_struct which means struct player.
  3. Same reason as 2.
  4. Same reason as 2 & 3.
  5. 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.
  6. 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?

Carl Norum
  • 219,201
  • 40
  • 422
  • 469