various questions about struct declarations in C

C, not C++.

There appear to be three possibilities:

(1)

1
2
3
4
struct {
  char name[50];
  int age;
} John, Jason;


(2)

1
2
3
4
typedef struct {
  char name[50];
  int age;
} John, Jason;


(3)

1
2
3
4
5
6
struct person {
  char name[50];
  int age;
};

struct person John, Jason;


I especially do not understand the point in (1) and (2).
The first declaration declares two objects John and Jason of unnamed structure.
The second declaration declares two typedef names John and Jason for an unnamed structure.
The third declaration declares a structure with tag person. Then two objects John and Jason of type struct person are created.
Last edited on
closed account (zb0S216C)
1) The first one creates an unnamed structure. Two instances of that unnamed structure are then declared. The region between the closing brace and the semi-colon is the only declaration context associated with the unnamed structure. After the only declarative region has passed, no more instances of the unnamed structure can be made simply because the compiler needs a type-identifier to create an instance.

2) Initially, the members are declared. After the declaration of all members, the unnamed structure is then assigned an identifier. In this particular case, two structures, "John" and "Jason", are declared. Typically, the region in which "John" and "Jason" are declared is used to declare instances of the structure as stated above. In this case, it's used to introduce type-names.

(3) This creates a structure named "person". Further on, two instances of "person", "John" and "Jason", are declared into the current scope.

Wazzak
Last edited on
Excellent explanations.

But when would (1) and (2) be preferred to (3)?

In the case of (1), when would an unnamed structure be desireable?

(2) seems to be a hack of (3). Why bother to use a typedef in order to
create an identifier, when the identifier can be created without it?
closed account (zb0S216C)
The 1st and 2nd are more restrictive than the 3rd because:

1) ...the 1st structure is completely unknown. It cannot have constructors, destructors, operators and member functions (in C++).

2) ... the 2nd structure's type-identifier isn't known until the closing-brace of the structure. Therefore, in C++, constructors, destructors, operators and member functions are not allowed.

divine fallacy wrote:
"In the case of (1), when would an unnamed structure be desireable?"

There aren't many uses but they can be used to a group local data in local scopes. For example:

1
2
3
4
5
6
7
8
9
void F( )
{
   struct
   {
      double W_;
      int X_;
   } Type_;
   Type_.X_ = 10;
}


divine fallacy wrote:
"(2) seems to be a hack of (3). Why bother to use a typedef in order to create an identifier, when the identifier can be created without it?"

The 2nd declaration allows the programmer to omit the "struct" prefix from instance declarations. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
struct X
{
   // ...
};

struct X X_; // "struct" must be here.

typedef struct
{
   // ...
} Y;

Y Y_; // "struct" doesn't have to be here. 

The reason behind this is that the compiler knows "Y" is now a type and doesn't need "struct" to indicate such a thing.

Wazzak
Last edited on
The 2nd declaration allows the programmer to omit the "struct" prefix from
instance declarations.


Is this (relatively trivial) tidiness technique the only reason to prefer
(2) to (3)?
Last edited on
closed account (zb0S216C)
Yes, but note that the identifier of each structure is introduced at different times.

Wazzak
Topic archived. No new replies allowed.