How am I able to use a class as a function parameter in itself?

This is not allowed as test will be infinitely big (it contains itself recursively).

struct test{
 test t;
};

However the following compiles fine:

struct test{
 int get(test t1);// or `int get(test t1){}`
 static test t2;
};

How does it know how much space to allocate for t1 on the stack, at that point test isn't complete yet. Same question goes for t2 and it's location on static memory.


Solution 1:

Case 1

Here we consider the statement static test t2;

From static documentation:

The declaration inside the class body is not a definition and may declare the member to be of incomplete type (other than void), including the type in which the member is declared:

struct S
{
   
   static S s;     // declaration, incomplete type (inside its own definition)
};

For the exact same reason your statement static test t2; is allowed/valid.

Case 2

Here we consider int get(test t1);

The above statement is a member function declaration and not a definition so this is also valid. That is, since it is a function declaraion you can use the incomplete type as parameter.

Case 3

Here we are considering:

int get(test t1){}

This works because:

The type of a parameter or the return type for a function definition shall not be an incomplete class type (possibly cv-qualified) unless the function definition is nested within the member-specification for that class (including definitions in nested classes defined within the class).

Solution 2:

One thing to note is that neither member functions nor static members affect the size of an object of a class. Functions are not reflected in object size.

You can have as many functions as you want and the class size will not change. The compiled code for the functions is stored in the "code" segment of memory.

Static data is also not stored in individual objects. No matter how many objects of class test you will have, the static data will remain the same size.

Since these declarations do not affect the size of test, it should be no problem for a compiler to delay finishing them until after the completion of the definition of test.