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...
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
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With