转自http://www.programlife.net/cpp-empty-class-object-sizeof-problem.html

之前在博客也写过一些空类相关的文章,记得当时候还有一个问题没有想明白,于是在经过了一番思索。空类问题似乎也是面试中经常涉及的问题,还是先看题目吧:

 

// Author: 代码疯子

// Blog: http://www.programlife.net/

// C++空类以及sizeof问题

#include <iostream>

using namespace std;

 

class Empty

{

public:

    char arr[0];

};

 

int main(int argc, char **argv)

{

    printf("%d\n", sizeof(Empty));

    // Empty em[10];

    return 0;

}

这里输出到底是多少呢?大部分或许会说是1。恩,试一试就知道了。在MS VC++环境下,确实输出是1.不过还会看到一个警告:

1>e:\2011\XXXX\probs\vs\ec.cpp(7) : warning C4200: 使用了非标准扩展 : 结构/联合中的零大小数组

1> 当 UDT 包含大小为零的数组时,无法生成复制构造函数或副本赋值运算符

 

如果硬是要把上面那个定义对象数组的注释去掉,那么VS就要怒了:

e:\2011\XXXX\probs\vs\ec.cpp(13) : error C2233: "em": 包含大小为零的数组的对象数组是非法的

 

提示错误C2233,不能定义大小为0的数组。接下来试一试GCC吧(这里的版本是gcc (GCC) 3.4.2 (mingw-special))。GCC竟然输出的是0,而且可以定义后面那个Empty em[10],可以看出这个版本的编译器的实现还是不太好。改一下代码试试:

// Author: 代码疯子

// Blog: http://www.programlife.net/

// C++空类以及sizeof问题

#include <iostream>

using namespace std;

 

class Empty

{

public:

    char arr[0];

};

 

int main(int argc, char **argv)

{

    // printf("%d\n", sizeof(Empty));

    Empty em[10];

    if (&em[0] == &em[2])

    {

        printf("Oops! This compiler appears to be crazy!\n");

    }

    else

    {

        printf("Just OK!\n");

    }

    for (int i = 0; i < 10; ++i)

    {

        printf("&em[%d] = 0x%08X\n", i, &em[i]);

    }

    return 0;

}

可以看到数组成员的地址都是一样的,这就给人不太好的印象了。

图片传不上来@@,诸位看原帖好了。。。

弄了这么多,我觉得这个问题就没有必要再深究了……懂得编译器对空类的优化基址,懂得不同的编译器结果可能不一样就行。

 

Copyed From 程序人生

Home Page:http://www.programlife.net

Source URL:http://www.programlife.net/cpp-empty-class-object-sizeof-problem.html