5

次のコードでコンパイル エラーが発生するのはなぜですか?


編集:元のコードが明確ではありませんでした-コードを別々のファイルに分割しました...


ファースト.h

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

public:
    First();
};

First.cpp

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

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

Firstクラス内でサイズを決定するのは問題ないようですが...

Second.h

class Second
{
public:
    Second();
};

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 に答える