3

typedef structクラスと関数の構造に奇妙な振る舞いがあります。違いは、最初のケースではすべての定義がクラス定義中に実行されることです。別のケース — 関数定義中。私のコードを見てください。

class C
{
public:
    //struct xStruct;
    typedef struct xStruct* xPtr;
    typedef struct xStruct {xPtr F;} xStructR;
    typedef struct { xPtr First; } xPtr_Type;
    void F(void **Var)
    {
        xPtr Ptr = 0;
        ((xPtr_Type*)Var)->First = Ptr->F; //errors
    }
};

void Fu()
{
    typedef struct qxStruct* qxPtr;
    typedef struct qxStruct {qxPtr qF;} qxStructR;
    typedef struct { qxPtr qFirst; } qxPtr_Type;
    qxPtr qPtr = 0;
    void **qVar = 0;
    ((qxPtr_Type*)qVar)->qFirst = qPtr->qF;
}

MS コンパイラ (cl.exe) でのコンパイル中に、次の 2 つのエラーが発生しました。

error C2027: use of undefined type 'xStruct'
error C2227: left of '->F' must point to class/struct/union

struct xStruct宣言のコメントを外すと、コードが機能します。しかし、宣言Fuなしの関数で同様のコードが正常に機能する理由がわかりませんか? struct xStructコンパイラには、クラス定義中のコード分析のより厳密なアルゴリズムがあるようです...

4

1 に答える 1

5

違いが 1 つあります。

class Cコンパイラでは、グローバル名前空間からの最初の出現を扱いますstruct xStruct。2 つ目はclass C名前空間からのものです。これが、割り当て中にエラーが発生した理由です。

class C
{
public:
    //struct xStruct;
    typedef struct xStruct* xPtr; 
    //      ^^^^^^^^^^^^^^  forward declaration of global type ::xStruct
    typedef struct xStruct {xPtr F;} xStructR;
    //      ^^^^^^^^^^^^^^^^^^^^^^^^  definition of local type C::xStruct
    typedef struct { xPtr First; } xPtr_Type;
    //                    ^^^^^ pointer to ::xStruct not C::xStruct
    void F(void **Var)
    {
       xPtr Ptr = 0;
       //   ^^^ pointer to global incomplete type
       ((xPtr_Type*)Var)->First = Ptr->F; //errors
       //                         ^^^^^^ using of ::xStruct which is incomplete
    }

グローバル関数の例では、両方の定義がグローバル名前空間からのものであるため、問題はありません。

それを証明するために、私はあなたの例を拡張しました-今では問題なくコンパイルされます:

class C
{
public:
    //struct xStruct;
    typedef struct xStruct* xPtr;
    typedef struct xStruct {xPtr F;} xStructR;
    typedef struct { xPtr First; } xPtr_Type;
    void F(void **Var);
};

struct xStruct {
  ::xStruct* F;    
};
void C::F(void **Var)
{
    xPtr Ptr = 0;
    ((xPtr_Type*)Var)->First = Ptr->F; //no errors
}
于 2012-10-26T22:00:27.827 に答える