Why in member function body I can define a obj of its own type?

I know that incomplete class type can not have a obj. But why the member function body can define a obj of its own type?

1
2
3
4
5
6
class Test {
public:
    void func() const {
        Test b;
    }
};
I think its called recursion. You can google it and read about it somewhere.
Standard wrote:
9.2.2
A class is considered a completely-defined object type (3.9) (or complete type) at the closing } of the class-specifier. Within the class member-specification, the class is regarded as complete within function bodies, default arguments, exception-specifications, and brace-or-equal-initializers for non-static data members (including such things in nested classes). Otherwise it is regarded as incomplete within its own class member-specification.
You're thinking about this as though it was a top-down interpreted language.

Consider a class definition where func is not implemented in-line:

1
2
3
4
5
6
7
8
9
10
11
12
// Test.h
class Test
{
public:
    void func() const;
};

// Test.cpp
void Test::func() const
{
    Test b;
}


It's no longer a conceptual problem is it?

TarikNeaj, this isn't recursion, not even close. This is a simple object creation. Now if this happened in the constructor, that would be recursion.
1
2
3
4
5
6
7
// recursion
class Test {
public:
    Test() {
        Test b;
    }
};
You're thinking about this as though it was a top-down interpreted language.
C++ uses single pass compilation model. That is why forward declarations are needed. For compiler nothing yet exist after current line. It is just some things inside class definition which are exception.
For compiler nothing yet exist after current line.

This doesn't conflict with my earlier comment.

A traditional interpreter executes the code as you go along

A compiler creates object files that still require link stage, perhaps even dynamic library loading at run-time.

If you went along "executing" the code in your head as you read it, it follows you might think the code was being executed in the same way by the CPU and ask the question that was asked.

The real point I was trying to prompt OP to think about is the quote from the standard:
Within the class member-specification, the class is regarded as complete within function bodies
There is even simpler case than the OP's:
1
2
3
4
struct foo {
  int bar() { return gaz; }
  int gaz;
};

That is legal, even though on line 2 we do not yet know that there is foo::gaz.

Intuitively, the compiler delays the compilation of the inlined member function bodies until the end of the class' definition.
Topic archived. No new replies allowed.