3
struct test{
 void call(test t1){
   //
 }
};

I have asked a similar question and found a few other links such as:

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

Incomplete types in member function definitions

But none of them answer this question:

The compiler needs to emit code to allocated space on the stack for t1, but at that point test is incomplete so how would it know how much space it needs?

Dan
  • 2,694
  • 1
  • 6
  • 19

3 Answers3

3

The answer is in the answers of your linked question (Incomplete types in member function definitions): the struct is complete in the context of the function definition.

Hence the C++ compiler will need to read the entire definition of struct test before generating the code of the call() function, but that is a compiler implementation issue.

It is also allowed to refer to member variables which are defined later in the struct definition:

struct test{
 void call(test t1){
   a += t1.a;
 }
 int a;
};
nielsen
  • 5,641
  • 10
  • 27
3

The class struct test is not an incomplete type.

From cppreference.com:

Incomplete type

  • the type void (possibly cv-qualified);
  • incompletely-defined object types
    • class type that has been declared (e.g. by forward declaration) but not defined;
    • array of unknown bound;
    • array of elements of incomplete type;
    • enumeration type from the point of declaration until its underlying type is determined.

All other types are complete.

Test it out yourself, put a test into your call function, like:

void call(test t1)
{
    std::cout << sizeof t1 << std::endl;
}
Erdal Küçük
  • 4,810
  • 1
  • 6
  • 11
  • maybe i'm thinking too much into how it would be implemented in the compiler. When the compiler is parsing `call` it hasn't even seen the rest if the struct yet. – Dan Jan 12 '22 at 15:37
  • If the compiler parses the declarations before the definitions, then it will know. – Erdal Küçük Jan 12 '22 at 15:40
  • you mean parse the entire struct declaration before function definition? – Dan Jan 12 '22 at 15:41
  • Compilation is not single pass. – Erdal Küçük Jan 12 '22 at 15:42
  • 1
    Right but when you say compiler parses the declarations, what do you mean by that? you mean declaration of other data types within the struct? – Dan Jan 12 '22 at 15:52
  • Compiling is a complex task, every compiler has its own methods. As an example, have a look at https://gcc.gnu.org/onlinedocs/gccint/Passes.html#Passes. As a developer (programmer) it is sufficient to know, that things being used, must have been declared beforehand and not incomplete. – Erdal Küçük Jan 12 '22 at 16:02
  • Im trying to clarify what you mean by **declarations**? i.e in `struct test {int a;}`, `a` is a declaration and compiler will need to read them all first? – Dan Jan 12 '22 at 16:06
  • It has to read everything. And no, `a` is not a declaration, `int a` on the other hand is. Have a lokk at the c++ standard, [4 General principles](https://timsong-cpp.github.io/cppwp/n4861/intro) and [5 Lexical conventions](https://timsong-cpp.github.io/cppwp/n4861/lex) for the translation steps. – Erdal Küçük Jan 12 '22 at 16:11
  • right i was also referring to `int a` (I thought that was clear). So compiler needs to read all the declaration of other data in the struct first. – Dan Jan 12 '22 at 16:13
  • 1
    More or less :) But honestly, if you are interested how the source files are processed, read the provided links. Hope you get an insight from them. – Erdal Küçük Jan 12 '22 at 16:16
1

Compiling a class definition is not a single-pass process.

Member functions are compiled only after it has been determined what the members are, just like if the function definitions were located "outside".

In other words, the compiler doesn't emit any code for the function until the class definition is complete.

molbdnilo
  • 64,751
  • 3
  • 43
  • 82