C Typedef and Struct Question

前端 未结 5 1852
别那么骄傲
别那么骄傲 2020-11-28 11:39

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

typedef struct IOPORT {  
    GPIO_TypeDef* port;  
    u16               


        
相关标签:
5条回答
  • 2020-11-28 11:55

    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.

    0 讨论(0)
  • 2020-11-28 11:57

    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.

    0 讨论(0)
  • 2020-11-28 12:03

    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 definition, I'll often lazily neglect declaring one or the other name.

    0 讨论(0)
  • 2020-11-28 12:08

    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.

    0 讨论(0)
  • 2020-11-28 12:19

    For the sake of readability it's preferred to express the original example in a form such as:

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

    ....which emphasizes the difference between type and instance.

    Furthermore, if you want to add initialisers you can do something like:

    typedef struct IOPORT_t {  
        GPIO_TypeDef* port;  
        u16           pin;  
    } IOPORT;
    
    struct IOPORT_t IOPORT2 = {
        .port = NULL,
        .pin = 25
      };
    

    or you can lose the typedef to initialise it directly:

    struct IOPORT_t {  
        GPIO_TypeDef* port;  
        u16           pin;  
    } IOPORT = {
        .port = NULL,
        .pin = 24
      };
    
    struct IOPORT_t IOPORT2 = {
        .port = NULL,
        .pin = 25
      };
    
    0 讨论(0)
提交回复
热议问题