C中是否需要typedef?

Typedef对于可移植名称,标记名称( typedef struct foo Foo; )以及保持复杂(函数)声明可读( typedef int (*cmpfunc)(const void *, const void *); )非常有用。

但是在C中是否存在真正需要typedef的情况? 通过简单地写出派生类型,你无法做到这一点。

澄清一点:我的意思是语言用户,而不是实施者。 整个stdint.h是第二类的一个很好的例子。

结论

感谢您的输入。 我想我可以总结为:

  • C99库需要typedef来实现各种(u)intN_t类型。
  • 在C89上,你真的想自己使用typedef来创建类似的可移植类型。
  • 使用va_arg宏时可能需要typedef,但我怀疑你在实践中会遇到这些衍生类型。

根据定义, typedef是别名。 因此,您始终可以使用实际类型替换别名。 否则它不会是别名。

这并不意味着避免使用typedef会是一个好主意。

谢谢大家的回答。 我自己看了一些,在C99中发现了这个,J.2未定义的行为:

在以下情况下,行为未定:[…]

  • va_arg宏的类型参数不能通过post fi xing a * (7.15.1.1)获得指向该类型对象的指针。

因此,当您想要将复杂的派生类型传递/提取到va_arg例如int (*)[]您需要将此类型的类型设置为可能的(更新/更正):

 typedef int (*intarrptr)[4]; intarrptr x = va_arg(ap, intarrptr); 

由于很难找到这个实际有用的案例,因此可以得出结论,对于typedef的必要性,它并不是一个强有力的论据。

来自维基百科:

typedef是C和C ++编程语言中的关键字。 typedef的目的是为现有类型指定替代名称,通常是那些标准声明繁琐,可能令人困惑或可能因实现而异的那些。 1

根据这个定义,不会永远不需要它,因为你总是可以写出扩展的forms。 但是,可能存在宏定义,其选择基于平台或其他类型使用的typedef。 因此,始终使用扩展forms可能不是非常便携。

这绝对是必需的,一个很好的例子是size_t,它在各种平台上都是typedef。

在检查C编译器是否符合ISO-C的测试套件中肯定需要关键字typedef。

在未明确应该使用typedef的代码中(如上面的测试套件),它通常非常有用,但从不必要,因为它只建立了另一种类型的别名。 它不会创建类型。

最后,我不会通过缩写typedef可以提供的数据来避免编译器对预处理源文件大小的限制。

是。 必须是固定大小的整数类型。 例如int32_t (并且您希望您的代码具有可移植性的机会)。

offsetof()宏需要structnamemembername ,因此不能与内联结构定义一起使用。 好吧,也许你的实现可以,但C标准不保证。

更新:正如评论中所指出的,这是可能的:

 struct blah { int a; int b; }; x = offsetof(struct blah, a); // legal 

但是内联结构定义不是:

 x = offsetof(struct {int a; int b;}, a); // illegal 

前者不包含关键字typedef ,但也无法内联结构定义。 “简单写出派生类型”表示哪个版本尚不清楚。

没有。

typedef不像C ++中的类那样创建一个真正的新类型,它只是创建一个类型别名 – 一个已经存在的其他东西的单一标识符。 在typedef中,您不定义任何新行为,语义,转换或操作符。

不,我认为我这么说是安全的!

我知道在C中没有明确需要typedef的情况。

不是“非常有用”意味着要求吗?

我甚至很难想到每个结构成员,指针,争论等的结构项目。

对我来说,typedef提供了抽象。 它使我的代码保持干净,非常容易理解。 你可以在没有typedef的情况下生活,就像没有所有高级语言并坚持使用汇编语言或机器语言一样。

个别程序员不需要创建自己的typedef。 没有普遍的规则说我不能写像

 int *(*(*x())[5])(); 

如果我愿意的话(虽然我公司的编码标准可能会不屑一顾)。

它们遍布标准库,但是( FILEsize_t等),所以你真的无法避免使用typedef名称。

我们使用typedef来保持代码平台的独立性。 例如,我们做类似的事情

 typedef unsigned char SHORT; 

这使代码更易读,易于移植。

如果没有typedef,如果在声明中使用struct,则必须每次都使用关键字struct。 使用typedef,您可以省略它。

 struct Person { char * name; }; struct Person p; /* need this here*/ typedef struct _Person { char * name; } Person; Person p; /* with typedef I can omit struct keyword here */