Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange behaviour with typedef struct in class

Tags:

c++

I have strange behavior with typedef struct constructions in classes and functions. The difference is that in first case all definitions are performed during class definition. Another case — during function definition. Look at my code.

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;
}

During compilation with MS compiler (cl.exe) i have two errors:

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

If i uncomment struct xStruct declaration my code works. But i can't understand why the similar code works fine in Fu function without struct xStruct declaration? It seems that compiler has more strict algorithms of code analysing during class definition...

like image 676
pmor Avatar asked Dec 27 '25 16:12

pmor


1 Answers

I see one difference:

In class C compiler treats first occurence of struct xStruct as from global namespace. The second is from class C namespace - that's why the error during assignment.

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
    }

In global function example both definitions are from global namespace, so no problem there.

To prove it I extended your example - now it compiles without problems:

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
}
like image 138
PiotrNycz Avatar answered Dec 30 '25 06:12

PiotrNycz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!