免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5674 | 回复: 13
打印 上一主题 下一主题

大牛请授课,为啥空的结构体sizeof输出为1 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-01 23:00 |只看该作者 |倒序浏览
代码如下:
  1. #include <iostream>
  2. using namespace std;

  3. struct CZeroLenArray
  4. {
  5.         char m_Data[];
  6. };

  7. struct CEmptyStruct
  8. {
  9.        
  10. };

  11. #define PRINT(X) do{cout<<#X<<":"<<X<<endl;}while(0)

  12. int main()
  13. {
  14.         PRINT(sizeof(CZeroLenArray));
  15.         PRINT(sizeof(CEmptyStruct));
  16.         return 0;
  17. }
复制代码
输出如下:
sizeof(CZeroLenArray):0
sizeof(CEmptyStruct):1

求大牛们指点一二。为啥空结构体要占用1个字节,相反灵活数组却占用空间为0

论坛徽章:
0
2 [报告]
发表于 2011-12-01 23:33 |只看该作者
假设有这么个应用:

CEmptyStruct arr[] = {... };

for (CEmptyStruct *p = arr; p != arr + sizeof(arr)/sizeof(*arr); p++)
{
    // do some thing with p
}

如果sizeof(CEmptyStruct) = 0,你想想这段代码会有哪些问题?

CZeroLenArray是不会有这种应用的。

论坛徽章:
0
3 [报告]
发表于 2011-12-02 08:52 |只看该作者
假设有这么个应用:

CEmptyStruct arr[] = {... };

for (CEmptyStruct *p = arr; p != arr + sizeof( ...
sonicling 发表于 2011-12-01 23:33



    CZeroLenArray是不会有这种应用的。 为什么?

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
4 [报告]
发表于 2011-12-02 10:09 |只看该作者
就是就是一个空的class,需要个地址

论坛徽章:
0
5 [报告]
发表于 2011-12-02 11:13 |只看该作者
侯捷的深入解析C++一書有過介紹
當時看過,不過現在記不起來
樓主可以再去查下

论坛徽章:
0
6 [报告]
发表于 2011-12-02 11:19 |只看该作者
不是侯捷写的,是侯捷翻的。

侯捷的深入解析C++一書有過介紹
當時看過,不過現在記不起來
樓主可以再去查下
shimmey 发表于 2011-12-02 11:13

论坛徽章:
1
天蝎座
日期:2013-12-06 18:23:58
7 [报告]
发表于 2011-12-02 12:48 |只看该作者
c++ 中struct是个类,怎么也有的地方放吧。空类也是类啊

论坛徽章:
0
8 [报告]
发表于 2011-12-02 13:17 |只看该作者
msdn:The sizeof operator never yields 0, even for an empty class.

sizeof(CZeroLenArray):0是在什么环境下运行的结果,应该都是1

论坛徽章:
0
9 [报告]
发表于 2011-12-02 15:05 |只看该作者
回复 8# linuxwyc


    起先我也觉得奇怪,char arr[];这样的成员声明能通过吗?看lz的代码似乎是通过了,所以也就算了。

后来查了一下,数组声明不指定bound,那么该数组的类型是incomplete type。C++白皮书3.9说:
A class that has been declared but not defined, or an array of unknown size or of incomplete element type, is an incompletely-defined object type. Incompletely-defined object types and the void types are incomplete types (3.9.1). Objects shall not be defined to have an incomplete type.


也就是说这样的成员声明是不符合标准的。但是实际使用的时候,gcc和vc都支持这种写法,并且自动指定bound为0,也就是等效于char arr[0];,因为效果一样,而且vc的警告都是“warning C4200: 使用了非标准扩展 : 结构/联合中的零大小数组”。但是再参看白皮书8.3.4说:
In a declaration T D where D has the form
D1 [constant-expression opt]

... If the constant-expression(5.19) is present, it shall be an integral constant expression and its value shall be greater than zero.


所以bound为0也不符合标准,所以vc给警告,但是允许。

而对于这种object with incomplete type,标准不允许,更不会说size是多少,所以他们的sizeof是unspecified的,我试了一下,vc下给的是1,和空结构一样,gcc给0,因为它支持这种用法,而且就是为了达到数组的越界或内存的重叠的目的。

评分

参与人数 1可用积分 +10 收起 理由
cugb_cat + 10 赞一个!

查看全部评分

论坛徽章:
0
10 [报告]
发表于 2011-12-02 15:58 |只看该作者
9楼给力
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP