5

为什么下面的代码会产生编译错误?


编辑:我的原始代码不清楚-我已将代码拆分为单独的文件...


第一.h

class First
{
public:
    static const char* TEST[];

public:
    First();
};

第一个.cpp

const char* First::TEST[] = {"1234", "5678"};

First::First()
{
    uint32_t len = sizeof(TEST); // fine
}

确定First班级内的大小似乎很好,但是......

第二个.h

class Second
{
public:
    Second();
};

第二个.cpp

#include "First.h"

Second::Second()
{
    uint32_t len = sizeof(First::TEST); // error
    uint32_t elements = (sizeof(First::TEST) / sizeof(First::TEST[0])); // error
}

我收到以下错误:'const char *[]': illegal sizeof operand

4

4 回答 4

8

sizeof 仅适用于完整类型。 const char* TEST[]在 First.cpp 中定义之前,它不是一个完整的类型。

sizeof(char*[10]) == sizeof(char*) * 10 == 40
sizeof(short[10]) == sizeof(short) * 10 == 20

// a class Foo will be declared
class Foo;
sizeof(Foo) == //we don't know yet

// an array bar will be defined.
int bar[];
sizeof(bar) == sizeof(int) * ? == //we don't know yet.

// actually define bar
int bar[/*compiler please fill this in*/] = { 1, 2, 3 };
sizeof(bar) == sizeof(int) * 3 == 12
// note bar is exactly the right size

// an array baz is defined.
int baz[4];
sizeof(baz) == sizeof(int) * 4 == 16

// initialize baz
int baz[4] = { 1, 2, 3 };
sizeof(bar) == sizeof(int) * 4 == 16
// note baz is still 4 big, the compiler doesn't control its size

要使其按您的意愿工作,您可以:

  • First::TEST数组的大小添加到其声明 ( static const char* TEST[2];)
  • 添加一个返回 sizeof 的新静态方法First::TEST。该方法不能内联,它必须在 First.cpp 中定义。
于 2009-12-08T16:02:45.897 回答
3

主要是因为First.cpp和Second.cpp的编译是相互独立的。

Second 中的 sizeof() (通常)在编译时解析,此时只有数组的声明是已知的,并且空间用于静态尚未分配无法计算。见http://en.wikipedia.org/wiki/Sizeof#sizeof_and_incomplete_types

于 2009-12-08T11:32:38.867 回答
2

展开 Second.cpp 时会更清晰。这是正在编译的全部内容(1 个编译单元):

class First
{
public:
    static const char* TEST[];

public:
    First();
};


class Second
{
public:
    Second();

    Second::Second()
    {
       uint32_t len = sizeof(First::TEST); // error
       uint32_t elements = (sizeof(First::TEST) / sizeof(First::TEST[0])); // error
    }
}

如果你看这里, First::TEST 显然没有大小,而 sizeof(FIRST::TEST) 是没有意义的。

为什么不只是有一个返回 TEST 长度的方法呢?

于 2009-12-08T11:19:26.507 回答
1

对我来说,即使是第一个sizeof(TEST)也无法编译,因为 TEST 没有用大小声明(仅在链接时解决)。

如果我更改TEST[]为 ,TEST[10]那么这两种情况都会编译。

这两个结果都是我所期望的。

您使用的是哪个编译器?

于 2009-12-08T11:03:34.340 回答