views:

689

answers:

4

What's the difference between these two declarations, and is one preferred over the other?

typedef struct IOPORT {  
    GPIO_TypeDef* port;  
    u16           pin;  
} IOPORT;  

typedef struct {  
    GPIO_TypeDef* port;  
    u16           pin;  
} IOPORT;
+10  A: 

the first allows you to use IOPORT inside the struct for refering to objects of the same type. useful in cases such as linked lists where a node has to refer to a node.

Victor
A: 

The first example allows you to use the object inside itself for things lie linked lists and trees (as Victor points out). The second is an example of anonymous types which experience has taught don't behave nicely with all compilers. So the first approach is probably recommended. If you're not concerned with the struct being able to reference itself you can always give it a name that's unlikely to conflict like __SOMEPREFIX_IOPORT__ for example.

Kevin Loney
+2  A: 

As far as which style is preferred, I prefer the 1st style (with the name in both the struct tag and as a typedef for the struct) simply because there are no drawbacks other than a few more characters in the source file. My IDE's struct snippet drops the name in both places, so I always get a typedef'ed struct name along with a struct tag name.

You get a few small benefits:

  • the "struct STRUCTNAME" can be used to declare pointers to the struct within the struct
  • you can get away with just using STRUCTNAME in either C or C++ code
  • you prevent a potential (even if very rare in practice) oddity in C++ having to do with the struct name being used for another object without error or warning

But, if I happen to manually type in the struct definintion I'll often lazily neglect declaring one or the other name.

Michael Burr
+2  A: 

C has four different namespaces, where the structure tag namespace is one of them. Hence:

struct foo { int bar; };

does not define a new type in the general sense. When you only have a structure tag, you need to prepend the keyword 'struct' in object declarations like this:

foo b; /* error */
struct foo b; /* correct */

In addition, you can instantiate a new object right away in the definition like this:

struct foo { int bar; } baz;

Where baz is an object of structure type foo. However, one often wants to define a structure as a new type, to save some writing. A complete type does not reference structure tags, so you can omit the 'struct' prefix during declarations.

typedef struct foo { int bar; } baz;

Still lets you declare objects with 'struct foo', since foo is the struct tag. But now it is promoted to a full type in the "normal" type namespace, where it is known as type baz. So with a typedef, the 'baz' field(s) has different semantics.

Unless you need to declare pointers to the structure type inside itself (linked lists, tree structures), omit it. Adding one which isn't required just pollutes the namespace.

Mads Elvheim