我在代码审核中遇到过这个问题:
typedef struct C { int i; };
它编译。</ p>
除了它是C风格,其中结构在一个单独的“命名空间”中,并且需要进行类型化以便以后使用,我发现这个typedef没有任何定义,这很奇怪......
那么:typedef
不需要类型参数和别名参数吗?
答案 0 :(得分:5)
快速浏览n3225并未显示要求存在名称的任何要求。最接近的文字只是说
在一个简单声明中,只有在声明一个类(第9节)或枚举(7.2)时,也就是说,当decl-specifier-seq包含一个类说明符时,可以省略可选的init-declarator-list。 ,一个带有类键(9.1)或枚举说明符的详细类型说明符。
所以你的代码似乎是有效的,但我认为它闻起来很糟糕。
答案 1 :(得分:2)
Thank you for testing your code with Comeau C/C++!
Tell others about http://www.comeaucomputing.com/tryitout !
Your Comeau C/C++ test results are as follows:
Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing. All rights reserved.
MODE:strict errors C++ C++0x_extensions
"ComeauTest.c", line 1: warning: declaration requires a typedef name
typedef struct C { int i; };
^
答案 2 :(得分:2)
是的,typedef
需要另一个论点。 typedef
不会做任何事情。
无论如何,这不是错误,只是弃用了typedef
。
C标准(6.7.7中的n1256)谈到typedef
。它没有说这种用法已被弃用,但编译器报告它是,因为这样的声明没有效果。
答案 3 :(得分:2)
您最有可能使用非常旧的编译器,它允许您编译该行。使用g ++ 4.3.0(已经很老了),没有任何其他选项,请给出:
g++ dfg.cpp
dfg.cpp:2: warning: ‘typedef’ was ignored in this declaration
因此,尝试使用符合c ++标准的编译器进行编译。
答案 4 :(得分:1)
确实,那是无效的。您使用关键字typedef
创建别名,然后不指定别名应该是什么!
(严格来说,它已被弃用,而非无效。但是嘿。)
答案 5 :(得分:1)
考虑以下几点之间的相似之处:
typedef struct C { int i; };
extern struct P { int i; };
GCC 4.2.1未启用明确警告(gcc -c xxx.c
)说明第一个:
xxx.c:1: warning: useless storage class specifier in empty declaration
xxx.c:2: warning: useless storage class specifier in empty declaration
请注意,它们只是警告;它们不是错误,因为标准允许使用符号,尽管它没有做太多。在每种情况下,该示例只是声明一种结构类型,可以使用名称struct C
或struct P
。存储类是无关紧要的,因为没有命名对象。在C ++中,这些声明还声明了类型C
和P
(但如果typedef
或extern was not there); in C, those types (
C and
P`)不会发生这种情况声明。
在C标准中,typedef
被视为存储类,如extern
和static
是存储类。这意味着以下代码是合法的:
typedef struct C { int i; } name1;
extern struct P { int i; } name2;
它声明了与以前相同的两种结构类型,但现在typedef
声明struct C
的别名为name1
,而extern
行声明了另一种翻译unit(TU)定义了name2
类型的struct P
变量。两者都不是空的(除了稍后在所示的2行TU中不使用这些定义)。
C标准允许许多奇怪的事情。例如:
int unsigned typedef u;
这是一种完全有效 - 但完全不正常 - 的写作方式:
typedef unsigned int u;
C99§6.11.5(在未来语言指导下)中有一节说:
6.11.5存储类说明符
除声明开头之外的存储类说明符的位置 声明中的说明符是一个过时的功能。
这使我的奇怪例子违反了§6.11.5。
struct C { int i; };
引入了类型C(以及struct C
)。正确的解决方法可能是删除存储类(typedef
),或者可能是引入名称作为struct C
的别名。由于代码在没有别名的情况下编译,因此删除存储类更可能是正确的。