在我最近的操作系统类中,我们有一堆对象定义如下:
typedef struct someobj {
... stuff ...
} someobj_t;
我知道那样做的还不错。
问题是,有时在给定的支持代码中,结构被称为struct someobj *some
,有时称为someobj_t *some
。是否有一个实际/有用的理由以这两种不同的方式引用结构,或者只是风格差异?
答案 0 :(得分:6)
虽然您可以使用typedef或结构名称,但有一个很好的理由不使用以typedef
结尾的 _t
名称。所有这些名称都由POSIX保留以供实现使用,并且可以指特定于实现的类型,或者可以在POSIX的未来版本中标准化。不幸的是,许多图书馆作者忽略了这一点。
我个人不希望对结构使用typedef
,但如果你选择使用它,至少要避免使用保留的命名空间。
答案 1 :(得分:5)
假设我们正在询问以下代码(问题中没有typedef
正如我正在写的那样,但我认为它应该在那里): < / p>
typedef struct someobj {
// content
} someobj_t;
实际上,通常只需省略名称someobj
并使用someobj_t
即可。但是,当您希望结构引用自身时,就是这种情况:
typedef struct someobj {
struct someobj* next;
// cannot say someobj_t* yet - typedef not complete
} someobj_t;
// and from now on, both struct someobj and`someobj_t are equivalent
答案 2 :(得分:2)
作者可能不知道您可以(或不愿意)省略someobj
。如果您只想要一种方式来引用类型,那么您可以写:
typedef struct {
...
} someobj_t;
正如科斯在另一个答案中提到的那样,只要结构不需要引用自身(例如在链表中),这就没问题了。为了最大程度的混淆,你总是可以这样做:
typedef struct someobj_t {
...
} someobj_t;
答案 3 :(得分:2)
假设你的意思是:
typedef struct someobj
{
/* ... */
} someobj_t;
一般的差异只是风格;有些人更喜欢坚持结构的“旧C”式命名(你必须在你引用那种类型的时候放置struct
关键字),其他人喜欢使用{更合成的方式} {1}}。
许多使用someobj_t
定义的符号的人觉得它更自然,因为它们通常来自其他语言(例如C ++,C#,......),而不需要typedef
的东西。在许多情况下,他们甚至会从声明中省略struct
名称,只留下struct
ed名称。
这两个符号的用法通常是等价的,但有一些注意事项;首先,在typedef
结束之前typedef
版本不存在,因此您无法使用_t
名称声明指向其内部结构的指针。
然后,仅在编译期间_t
“存在”;这意味着编译器和调试器将使用非typedef
ed名称引用您的符号。如果您使用没有“真实”结构名称的typedef
,当您必须使用某些编译器/调试器调查错误时,您可能会生气,因为您无法引用“真实”结构名称,因为{{1没有真实姓名的ed结构实际上是匿名结构。
如果您必须使用MIDL和类似的东西导出您的结构,这可能会特别成问题;有关详细信息,请参阅Raymond Chen的this post。
最后但并非最不重要的是,您可以使用真实的结构名称进行前向声明;如果您没有结构名称(但只有typedef
),则无法进行前向声明。
答案 4 :(得分:1)
我认为你的意思是
typedef struct someobj {
... stuff ...
} someobj_t;
这允许您使用someobj_
t作为类型而不是struct someobj
。两种符号都是等价的。