Ita*_*ypk 54 c c++ struct visual-studio-2010
我在现有代码库中有以下(工作)代码,用于C和C++之间共享的包含文件,在MSVC(2010)和Windows DDK上编译:
struct X {
USHORT x;
} typedef X, *PX;
Run Code Online (Sandbox Code Playgroud)
和:
enum MY_ENUM {
enum_item_1,
enum_item_2
} typedef MY_ENUM;
Run Code Online (Sandbox Code Playgroud)
据我所知,正确的定义应如下所示:
typedef struct {
USHORT x;
} X, *PX;
Run Code Online (Sandbox Code Playgroud)
有下面的表格是否有任何目的?我错过了什么吗?
Oli*_*rth 56
这两个事实typedef <type> <alias>及<type> typedef <alias>有效简单地来自于语言的语法定义.
typedef被归类为存储类规范器(就像static,auto),类型本身被称为类型说明符.根据标准第6.7节中的语法定义,您将看到它们可以互换:
declaration:
declaration-specifiers init-declarator-list ;
declaration-specifiers:
storage-class-specifier declaration-specifiers
type-specifier declaration-specifiers
type-qualifier declaration-specifiers
function-specifier declaration-specifiers
init-declarator-list:
init-declarator
init-declarator-list , init-declarator
init-declarator:
declarator
declarator = initializer
Run Code Online (Sandbox Code Playgroud)
(当然,请注意,结构和非结构同样如此,这意味着它double typedef trouble;也是有效的.)
oua*_*uah 18
正如其他人所说,typedef是存储类说明符,与其他存储类说明符一样,您也可以在类型和声明符之间放置说明符.
虽然这是有效的,但它也是一种应该避免的形式,因为C将其标记为过时功能:
(C11,6.11.5p1)"在声明中声明说明符开头之外的存储类说明符的放置是一个过时的功能."
两者都有相同的含义.这两种形式都有效:
typedef <existing_type> <new_type>
<existing_type> typedef <new_type>
Run Code Online (Sandbox Code Playgroud)
您可以typedef通过以下两种方式获得上述结构:
struct X {
USHORT x;
}typedef X, *PX; // <existing_type> typedef <new_type>
Run Code Online (Sandbox Code Playgroud)
要么
typedef struct {
USHORT x;
} X, *PX; // typedef <existing_type> <new_type>
Run Code Online (Sandbox Code Playgroud)
你真的被允许以你想要的任何顺序放置所有声明说明符!任何*指针的位置和实际的声明符(变量或新类型名称)都很重要,但所有typedef int unsigned const static等等的东西都可以按任何顺序排列.
如果你看一下C的官方语法,它只是说:
declaration:
declaration-specifiers init-declarator-list ;
Run Code Online (Sandbox Code Playgroud)
的declaration-specifiers是所有的存储类型说明符(typedef,extern等),类型说明符(实际的类型,如int或struct X),类型限定符(const和volatile),以及其他一些不常见的.他们的命令并不重要.第二部分是init-declarator-list,它是变量或新类型名称(在typedef的情况下),任何*字符,变量(int x = 3)的初始化等等.声明器部分中的事物顺序很重要,但不是声明说明符中的顺序.
免责声明:这不是一个技术问题,而是一个实际的答案.有关技术问题,请参阅其他答案.这个答案读起来是固执的和主观的,但请在我尝试解释大局时请耐心等待.
struct是一个奇怪的野兽,因为你放在右括号}和分号之间的东西;是指那些括号内或之前的内容.我知道为什么会这样,而且从语法角度来说它确实有意义,但我个人觉得这很反直觉,因为花括号通常意味着范围:
反直觉的例子:
// declares a variable named `foo` of unnamed struct type.
struct {
int x, y;
} foo;
foo.x = 1;
// declares a type named `Foo` of unnamed struct type
struct {
int x, y;
} typedef Foo;
Foo foo2;
foo2.x = 2;
// declares a type named `Baz` of the struct named `Bar`
struct Bar {
int x, y;
} typedef Baz;
// note the 'struct' keyword to actually use the type 'Bar'
struct Bar bar;
bar.x = 3;
Baz baz;
baz.x = 4;
Run Code Online (Sandbox Code Playgroud)
如果像这样使用,structs和typedefs 的密集语法可能会出现许多微妙的问题.如下所示,很容易意外地声明变量而不是类型.编译器只有有限的帮助,因为几乎所有组合在语法上都是正确的.它们并不一定意味着您尝试表达的内容.这是一个绝望的坑.
错误的例子:
// mixed up variable and type declaration
struct foo {
int x, y;
} Foo;
// declares a type 'foo' instead of a variable
typedef struct Foo {
int x, y;
} foo;
// useless typedef but compiles fine
typedef struct Foo {
int x, y;
};
// compiler error
typedef Foo struct {
int x, y;
};
Run Code Online (Sandbox Code Playgroud)
出于可读性和维护的原因,我更喜欢单独声明所有内容,而不是将任何内容放在最后的大括号后面.直观的语法很容易超过额外代码行的成本.我认为这种方法可以很容易地做出正确的事情而且很烦人做错事.
直观的例子:
// declares a struct named 'TVector2'
struct TVector2 {
float x, y;
};
// declares a type named 'Vector2' to get rid of the 'struct' keyword
// note that I really never use 'TVector2' afterwards
typedef struct TVector2 Vector2;
Vector2 v, w;
v.x = 0;
v.y = 1;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2483 次 |
| 最近记录: |