Eckel Vol1, pg283, Incomplete type specification, what is the compiler doing?
<pre><code>struct X;

struct Y {
  void f(X*);
};

struct X { //definition
private:
  int i;
public:
  friend void Y::f(X*);
  &lt;SNIP'd&gt;
};
</code></pre>

<blockquote>
  <p>"struct <code>Y</code> has a member function <code>f()</code> that will modify an object of type <code>X</code>. This is a bit of a conundrum because the <strong>C++ compiler requires you to declare everything before you can refer to it</strong>, so struct <code>Y</code> must be declared before its member <code>Y::f(X*)</code> can be declared as a friend in struct <code>X</code>. But for <code>Y::f(X*)</code> to be declared struct <code>X</code> must be declared first!</p>
  
  <p>Here's the solution. Notice that <code>Y::f(X*)</code> takes the address of an <code>X</code> object. This is critical because <strong>the compiler always knows how to pass an address, which is of a fixed size regardless of the object being passed</strong>, even if it doesn't have full information about the size of the type."</p>
</blockquote>

<p>So here we have: </p>

<pre><code>struct X; struct Y { ... }; struct X { ... };
</code></pre>

<p>My question is this:</p>

<ol>
<li><p>Why does the compiler insist that <code>X</code> be declared incompletely as: <code>struct X;</code>??</p>

<p>After all, as the author notes: "compiler always knows how to pass an address 
which is of a fixed size." This is just a declaration that tells the compiler that <code>X</code> is a struct and soon to follow, so why is the compiler so insistent that you type out the letters: struct <code>X</code>; after all I'm not using <code>X</code> per se?? There's no assembly language code being generated at that point. and when it reads the <code>X*</code> surely it can tell that it's an address(pointer).. why is: <code>struct X;</code> needed?</p>

<p>The whole point of declaring functions is for type checking before actual 
usage. So if I do: </p>

<pre><code> int foo(void); foo(30); 
</code></pre>

<p>and the compiler will howl. But in the above, if I don't say: <code>struct X;</code> what difference does it make? Is he just checking my spelling of <code>X</code> (the function-name)?</p></li>
<li><p>Why doesn't reversing the placement of struct Y and X work? Like so:<br>
<code>struct Y; struct X { ... }; struct Y { ... };</code><br>
I get:<br></p>

<blockquote>
  <p>error: invalid use of incomplete type <code>'struct main()::Y'</code></p>
</blockquote>

<p>Obviously, the compiler isn't satisfied with my incomplete type specification for 
<code>Y</code> (<code>struct Y;</code>). But what precious little nugget of info is missing?? After
all struct <code>Y</code>; should tell the compiler that <code>Y</code> is soon to follow (same as doing
what we were doing in Q1: <code>struct X; struct Y {}; struct X{};</code> )</p></li>
<li><p>Why does the author refer to struct <code>X</code> as a definition? If i do:
<code>struct X { ... };</code> this is surely a declaration? And when I instantiate the
structure like so: <code>X</code> foo; then it's a definition? Correct?</p></li>
<li><p>How do I do this:</p>

<pre><code>struct X {
  friend void Y::f(X*);
  void f(Y*);
};

struct Y {
  friend void X::f(Y*);
  void f(X*);
};
</code></pre></li>
</ol>
