Why should we typedef a struct so often in C?

后端 未结 15 2894
無奈伤痛
無奈伤痛 2020-11-21 23:58

I have seen many programs consisting of structures like the one below

typedef struct 
{
    int i;
    char k;
} elem;

elem user;

Why is i

15条回答
  •  灰色年华
    2020-11-22 00:19

    Linux kernel coding style Chapter 5 gives great pros and cons (mostly cons) of using typedef.

    Please don't use things like "vps_t".

    It's a mistake to use typedef for structures and pointers. When you see a

    vps_t a;
    

    in the source, what does it mean?

    In contrast, if it says

    struct virtual_container *a;
    

    you can actually tell what "a" is.

    Lots of people think that typedefs "help readability". Not so. They are useful only for:

    (a) totally opaque objects (where the typedef is actively used to hide what the object is).

    Example: "pte_t" etc. opaque objects that you can only access using the proper accessor functions.

    NOTE! Opaqueness and "accessor functions" are not good in themselves. The reason we have them for things like pte_t etc. is that there really is absolutely zero portably accessible information there.

    (b) Clear integer types, where the abstraction helps avoid confusion whether it is "int" or "long".

    u8/u16/u32 are perfectly fine typedefs, although they fit into category (d) better than here.

    NOTE! Again - there needs to be a reason for this. If something is "unsigned long", then there's no reason to do

    typedef unsigned long myflags_t;
    

    but if there is a clear reason for why it under certain circumstances might be an "unsigned int" and under other configurations might be "unsigned long", then by all means go ahead and use a typedef.

    (c) when you use sparse to literally create a new type for type-checking.

    (d) New types which are identical to standard C99 types, in certain exceptional circumstances.

    Although it would only take a short amount of time for the eyes and brain to become accustomed to the standard types like 'uint32_t', some people object to their use anyway.

    Therefore, the Linux-specific 'u8/u16/u32/u64' types and their signed equivalents which are identical to standard types are permitted -- although they are not mandatory in new code of your own.

    When editing existing code which already uses one or the other set of types, you should conform to the existing choices in that code.

    (e) Types safe for use in userspace.

    In certain structures which are visible to userspace, we cannot require C99 types and cannot use the 'u32' form above. Thus, we use __u32 and similar types in all structures which are shared with userspace.

    Maybe there are other cases too, but the rule should basically be to NEVER EVER use a typedef unless you can clearly match one of those rules.

    In general, a pointer, or a struct that has elements that can reasonably be directly accessed should never be a typedef.

提交回复
热议问题