奇特的编译 error: C2016
我正在搭建全新的HugeCalc架构,尝试采用mathe曾给出的建议。但编译时遇到一条提示 error C2016: C requires that a struct or union has at least one member
为了分析问题,我写了个简单的测试程序:typedef struct _HI{} *PHI;
int main(void)
{
int i;
PHI p;
p = (PHI)&i;
return 0;
}如果存成 test.cpp,在 VC2008 及 VC6 下均顺利编译通过。
但若修改文件名为 test.c,在VC6 下提示:Deleting intermediate files and output files for project 'test - Win32 Debug'.
--------------------Configuration: test - Win32 Debug--------------------
Compiling...
test.c
e:\jason\test\test.c(1) : error C2059: syntax error : '}'
e:\jason\test\test.c(6) : error C2065: 'PHI' : undeclared identifier
e:\jason\test\test.c(6) : error C2146: syntax error : missing ';' before identifier 'p'
e:\jason\test\test.c(6) : error C2065: 'p' : undeclared identifier
Error executing cl.exe.
test.exe - 4 error(s), 0 warning(s)
在VC2008下提示:------ Rebuild All started: Project: test, Configuration: Debug Win32 ------
Deleting intermediate and output files for project 'test', configuration 'Debug|Win32'
Compiling...
test.c
e:\jason\test\test.c(1) : error C2016: C requires that a struct or union has at least one member
Build log was saved at "file://e:\Jason\test\Debug\BuildLog.htm"
test - 1 error(s), 0 warning(s)
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========
我想问的是:为什么C中不允许定义空的结构体?而C++既然允许,是什么原因呢? C++编译时,应该是会将所有的class,struct都统一为一种C++对象模型。对编译器而言,在语义上,class 和 struct是等价的。
而C++允许定义空类,每个类对象都起码占一个字节(不考虑内存对齐)。
具体的,《Inside The C++ Object Model》讲过。 是的,C不允许空对象,但是C++由于支持模板类等,经常广泛使用空对象。
不过LZ可以试着直接使用:
typedef struct _HI *PHI;
也就是不定义_HI而直接使用其指针。 2# medie2005
看了你的说明,
我突然想到在 C++ 里,class 里会隐藏一个指针,用来记录成员函数地址,或者是虚拟函数表的索引号。
因为不同的class其成员函数地址肯定不一样,正是有因为这个隐藏的变量,可以让编译器进行区分。
而C中不存在上述机制,所以编译器无法进行空结构的区分。
不知上述观点是否正确? 不正确。 编译器是通过类名来区分是否是同一个类的指针。 3# mathe
mathe 就是高,很快就想到了变通手法。typedef struct _HI *PHI;
typedef struct _HX *PHX;
PHI HI_New( void );
PHX HX_New( void );
void HI_Del( PHI pHI );
void HX_Del( PHX pHX );如果混用了 PHI/PHX 类型,比如:HX_Del( HI_New() );
则编译时不会报error,但会报 warning C4133: 'function' : incompatible types - from 'PHI' to 'PHX'
应该说基本达到提醒警告的目的了。 不正确。 编译器是通过类名来区分是否是同一个类的指针。
mathe 发表于 2010-3-18 08:29 http://bbs.emath.ac.cn/images/common/back.gif
那为什么C中不可以以结构名进行区分呢? C++允许定义空对象,也就是必须允许定义空类。
但一个空类,可以实例化为多个空对象,如何区分这些空对象?
比如class A是空类,定义Atest1, test2。
在编译器角度,如何区分test1和test2?
起码,每个空对象都要占用内存空间,以区别于其他空对象。 C中就是用结构名来区分两个不同的结构的。
所以
HX_Del( HI_New() );
会报告警告,应为这时不同类型之间指针的转化(结构名不同)。
对于C++中的空对象,不会产生真正的内存空间的消耗,或者我们可以赋予任意内存地址空间。具有意义的只有其逻辑值。对于同一个空对象的两个不同实例,通过地址区分它们没有意义。
而C++中的空类主要用于模板类,比如我们可以如下定义一个functor
class compare{
public:
bool operator()(int a, int b)const;
};
然后我们可以通过比如
compare c;
c(1,2)
来调用这个函数。 既然“C中就是用结构名来区分两个不同的结构的”,
那究竟是什么原因必须规定“C requires that a struct or union has at least one member”?
我的意思是:在主题帖的定义下,我们人感觉是合理的,为什么编译器会拒绝呢?根本原因是什么呢?
页:
[1]
2