为什么"typedef struct foo foo;" 认为有害吗?

Phi*_*lip 12 c coding-style

C vs C++中的typedef和struct命名空间中,其中一条注释似乎意味着暴露某些注释struct foo优于使用typedef ...

typedef struct foo foo;
Run Code Online (Sandbox Code Playgroud)

...然后使用foo而不是struct foo整个API.

后一种变体有任何缺点吗?

Kar*_*ath 9

唯一的缺点(*)是它隐藏了foo一个结构的事实,而不是一些内置类型的别名.

注意(*):这对你来说是否有缺点.

  • 它对完全不透明有好处(见下面的第一条评论).
  • 要了解为什么有些人认为这是一个缺点,请检查linux内核编码风格(typedefs章节).

  • 我认为这是一个功能.当然,它并没有真正隐藏任何东西,但它建议更好地使用库的辅助函数,而不是直接搞乱数据. (3认同)

Jon*_*ler 8

这取决于你喜欢这个词多少struct.如果你觉得你的程序将通过自由的洒水struct thatstruct tother(你struct this当然不能用C++)来清楚,那么一定要使用这个struct版本.

就个人而言,我不认为重复struct提供任何好处,我很乐意使用这个typedef名称.而由于C++有效地提供了typedef struct xyz xyz;自动声明(这是不太准确的,不只是因为你可以明确地写在C++中,但它是足够接近,你可能不必担心它),我觉得它非常感使用在C C编译器同样是满意的话,那么我通常使用typedef struct tag tag;,然后使用tagtag *在需要的地方.


有关替代但完全可行的视图,请阅读Linux内核编码样式指南.


请注意,C2011允许您重新定义a typedef,只要它别名相同的类型:

ISO/IEC 9899:2011§6.7声明

语义

5声明指定一组标识符的解释和属性.标识符的定义是该标识符的声明:

- 对于一个对象,导致为该对象保留存储;

- 对于一个功能,包括功能体; 119)

- 对于枚举常量,是标识符的(唯一)声明;

- 对于typedef名称,是标识符的第一个(或唯一)声明.

与C99相比,这是不可能的:

ISO/IEC 9899:1999§6.7声明

语义

5声明指定一组标识符的解释和属性.标识符的定义是该标识符的声明:

- 对于一个对象,导致为该对象保留存储;

- 对于一个功能,包括功能体; 98)

- 对于枚举常量或typedef名称,是标识符的(唯一)声明.

只要您保持一致,这就简化了类型定义的创建(但只有在与您相关的每个平台上都有足够兼容的C2011编译器时).


oua*_*uah 7

是否为typedef结构类型:

以下是一些意见(所有针对typedefing结构):

来自OpenBSD风格指南:

"避免对结构类型使用typedef.这使得应用程序不可能不透明地使用指向这种结构的指针,这在使用普通的struct标签时既可能又有益."

从Linux内核编码风格:

" 将typedef用于结构和指针是一个错误."

来自Peter Van der Linden的专家C编程:

"不要为typedef打扰结构.他们所做的只是保存你写"struct"这个词,这是你可能不应该隐藏的线索."

  • OpenBSD样式指南在两个帐户上都是错误的:`typedef struct foo foo;`可以用于不透明指针,也是有效的C++; 虽然如果你不使用typedef,你可以声明指针变量而没有显式的前向声明`struct foo;`,你应该添加一个:否则,如果结构的第一次出现在函数声明中,该类型将具有原型范围,这是很少需要的 - 虽然由于类型兼容性规则它实际上并不是有害的,编译器可能会警告它... (4认同)
  • 我发现Linux内核风格一般都很模糊,不考虑可移植性(在编写可移植代码时,opaque类型非常有用),所以我不认为它应该被视为Linux内核编程之外的某种形式的权限.在围栏的另一边,Windows API完全相反:它始终是typedefs远结构.我认为这主要是风格问题. (4认同)
  • @Christoph:天哪,所以OpenBSD的引用相当于"避免对结构类型使用typedef.这将迫使我们在头文件中添加我们结构的前向声明,声明函数指向那些结构.我们选择不这样做."?听起来非常像当地的风格规则,通常不适用. (3认同)