2012-09-18 2 views
7

次のコードは、私には罰金になります。C2070 - 違法のsizeofのオペランド

#include <stdio.h> 

    template <typename T> 
    struct A 
    { 
     static float m_kA[]; 
    }; 

    template <typename T> 
    float A<T>::m_kA[] = {1.0f, 2.0f, 3.0f}; 

    int main() 
    { 
     printf("%d\n", 
      sizeof(A<unsigned int>::m_kA)/
      sizeof(A<unsigned int>::m_kA[0])); 
     return 0; 
    } 

しかし、私はVC9でコンパイルするとき、私は次のエラー

error C2070: 'float []': illegal sizeof operand 

を取得し、私はこのコードをコンパイルすることを期待します。何か不足していますか?誰もがこの奇妙な動作を修正する方法を知っていますか?テンプレートなしで全く同じことがうまくコンパイルされ、3が出力されます。

テンプレートを削除することはオプションではないことに注意してください。この例では、配列を含む型がテンプレートである必要があるコードで発生している問題を再現しました。

おかげ

+1

FWIW、GCC 4.7.1上で正常にコンパイル:http://liveworkspace.org/code/19f48dbdb07463b08a310c168ab59a67。それがもう一つのMSVCのバグなのか見てみてください。 – chris

+0

私は、表現があなたが計算していると思っているものを計算しているとは思わない。 – Nobody

+4

@Nobody 'sizeof array/sizeof array [0]'は、配列の長さを計算する一般的なイディオムです。それは何を計算すると思いますか、他の人が計算したと思うと思いますか? – hvd

答えて

5

http://ideone.com/3ssVi

それはG ++でコンパイル罰金。私の知る限り、それは、このバグに関連することができます見ることができるよう

http://connect.microsoft.com/VisualStudio/feedback/details/759407/can-not-get-size-of-static-array-defined-in-class-template

+0

報告されたバグは、私が持っているのと同じ問題を示しています。私はちょうどその周りに道を見つけることを試みます。 – valerio

4

これはよく定義されています。クラス定義でm_kAがタイプfloat[]で宣言されていることに注意してください。これは不完全な型であり、sizeofと一緒に使用することはできません。 m_kAの定義では、タイプfloat[3]に再宣言されます。その後、sizeofを使用しても問題ありません。 (8.3.4は、配列宣言の意味を支配する。)

を3.4.6の[basic.lookup.udir]と名前空間エイリアス・ディレクティブを使用する:タイプのすべての調整後

10(のtypedefこの間(7.1.3)がそれらの定義に置き換えられている)、配列オブジェクトの宣言がメジャーの有無によって異なる配列型を指定できる点を除けば、与えられた変数または関数を参照するすべての宣言によって指定される型は同一でなければならない配列境界(8.3.4)。型識別に関するこの規則の違反は、診断を必要としない。 3.9.2化合物のタイプ[basic.compound]から

6 [...]配列オブジェクトの宣言された型は、未知のサイズの配列であるので、1で不完全であるかもしれません翻訳単位を指し、後で完結する。それら2つの点(「Tの未知の配列の配列」および「N Tの配列」)における配列タイプは、異なるタイプである。 [...]

コンパイラの問題を回避するには、m_kAを完全な型で完全に宣言することです。サイズを保持している別の静的メンバーも役に立ちます。

[私はC++ 11から引用していますが、私の知る限りC++ 03は同じ規則に従っています。 ]

+1

C++が私にそれを許せば、私は初期化子をインライン化することができます。問題は、私が知る限り、ローカル変数やグローバル変数に対してのみ行うことができ、テンプレートを作成することができないということです。 また、私が前に言ったように、VC9をこれで正当化するのは難しいと思います。 – valerio

+1

もう一つ考えると、[this](http://pastebin.com/tumC3NBU)(注:有効でないC++)のような構造体は、型*がおそらく 'floatではなくfloat []'のままであるべき正当な理由です[3] 'テンプレートで。しかし、今削除された議論で見たように、タイプは実際には 'float [3]'です。 – hvd

関連する問題