在C中,可以定义一个struct,typedefed,并声明为:
typedef struct {
int bar;
} Foo;
Foo foo;
或者:
struct Foo {
int bar;
} foo;
typedef struct Foo Foo;
我认为这有点不一致且过于冗长。我希望它能像C ++一样工作。
在C ++中,您不需要指定typedef struct Foo Foo;
来声明像Foo foo;
而不是struct Foo foo;
这样的结构。为什么没有将它引入C标准或作为编译器标志选项?如果在C中将typedef struct
作为可选项,是否有任何C代码会中断?
答案 0 :(得分:8)
是可选。
struct mystruct {
int x;
};
struct mystruct y;
结构定义位于“标记”名称的单独名称空间中。这样它们就不会与函数或变量名冲突,所以你可以这样做:
struct stat st;
int r = stat("/path/file.txt", &st);
您注意到stat
是函数的名称和结构的名称,但它们不会发生冲突?这是一个真实的例子,请参阅stat (2)。如果你消除了这个,旧的代码将无法编译。 typedef
在与函数和变量相同的命名空间中创建名称。
struct stat { ... };
int stat(const char *path, struct stat *buf);
typedef struct stat stat; // ERROR
某些样式指南使用typedef提倡不,只需在任何地方输入struct stat
。无论你是否同意这一点,它都存在于各个地方(例如Linux内核!),C标准委员会反对破坏现有的C代码库。
在C ++中,通过使struct
可选来维护与C代码的兼容性,但是如果定义一个与结构同名的函数,则需要在变量定义中显式使用struct
: / p>
stat st; // error! stat is a function
struct stat st; // Ok
int r = stat("/path/file.txt", &st);
答案 1 :(得分:3)
嗯,你有这个:
struct Foo {
int bar;
} foo;
typedef struct Foo Foo;
在第一行中,您将在结构名称空间中定义标识符Foo
(不是在C ++意义上)。您可以使用它并通过将参数类型定义为struct Foo
来定义新定义类型的变量或函数参数:
void f(struct Foo argument);
在上面的函数中,struct是必需的。
第二行在全局名称空间中添加了一个类型别名Foo
,因此您只需编写:
void f(Foo argument);
在上面的函数声明中,不再需要struct关键字。请注意,由于两个标识符名称空间不同,因此在结构和全局空间中定义Foo
不是错误,因为它不是重新定义相同的标识符,而是在不同的位置创建不同的标识符。
使差异更明显:
typedef struct Foo {
int x;
} Bar;
void Foo() { } // correct
//void Bar() {} // error: symbol Bar already defined as an alias to 'struct Foo'
您可以定义一个具有相同结构名称的函数,因为标识符保存在不同的空格中,但是您无法定义与typedef
同名的函数,因为这些标识符会发生碰撞。
所以,常见的习惯用法是:
typedef struct Foo {
int bar;
} Foo;
Foo foo;
编辑(更多信息):
在C ++中,它略有不同,因为定位符号的规则已经巧妙地改变了。 C ++仍保留两个不同的标识符空间,但与C中不同,当您只在类标识符空间中定义符号时,不需要提供struct / class关键字。搜索规则有哪些变化,而不是定义标识符的位置。编译器将搜索全局标识符表并在' Foo'之后还没有发现它会搜索Foo'在类标识符中。
答案 2 :(得分:2)
编译器可以自由地进行扩展,但由于没有编译器 委员会没有理由将其标准化。
是否有任何C代码的例子,如果是typedef结构会破坏 是否可以在C?
中选择
大量。考虑类似的事情:
struct Foo {
int bar;
/* ... */
};
void Foo(void) {
/* ... */
}
它将停止编译。