Eckel Vol1,pg283,不完整的类型规范,编译器在做什么

Eckel Vol1, pg283, Incomplete type specification, what is the compiler doing?

本文关键字:编译器 什么 类型 pg283 Vol1 Eckel      更新时间:2023-10-16
struct X;
struct Y {
  void f(X*);
};
struct X { //definition
private:
  int i;
public:
  friend void Y::f(X*);
  <SNIP'd>
};

"struct Y 有一个成员函数f(),它将修改类型为 X 的对象。这有点难题,因为C++编译器要求您先声明所有内容,然后才能引用它,因此必须先声明结构Y,然后才能声明其成员Y::f(X*)在结构X中声明为友元。但是要声明Y::f(X*)结构X必须先声明!

这是解决方案。请注意,Y::f(X*) 采用X对象的地址。这是至关重要的,因为编译器始终知道如何传递地址,无论传递的对象如何,该地址都具有固定大小,即使它没有有关类型大小的完整信息。

所以这里有:

struct X; struct Y { ... }; struct X { ... };

我的问题是这样的:

  1. 为什么编译器坚持将X不完全声明为:struct X;??

    毕竟,正如作者所指出的:"编译器总是知道如何传递地址这是固定大小的。这只是一个声明,告诉编译器X是一个结构体并且很快就会遵循,那么为什么编译器如此坚持要你输入字母:struct X ;毕竟我本身没有使用X??此时不会生成汇编语言代码。当它读取X*时,它肯定可以说它是一个地址(指针)。为什么:需要struct X;

    声明函数的全部意义在于实际进行类型检查用法。因此,如果我这样做:

     int foo(void); foo(30); 
    

    编译器会嚎叫。但是在上面,如果我不说:struct X;有什么区别?他只是检查我X(函数名称)的拼写吗?

  2. 为什么反转结构体 Y 和 X 的位置不起作用?这样:

    struct Y; struct X { ... }; struct Y { ... };我得到:

    错误:未使用不完整的类型 'struct main()::Y'

    无效

    显然,编译器对我不完整的类型规范不满意 Ystruct Y; ).但是缺少什么宝贵的信息??后所有结构Y ;应该告诉编译器Y即将跟进(与我们在第一季度做了什么:struct X; struct Y {}; struct X{};

  3. 为什么作者将结构X称为定义?如果我这样做: struct X { ... };这肯定是一个宣言?当我实例化结构如下:X福;那么这是一个定义?正确?

  4. 我该怎么做:

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

为什么编译器坚持将 X 不完全声明为:结构体 X??毕竟,正如作者所指出的:"编译器总是知道如何传递一个固定大小的地址。

你没有:这也有效:

struct Y { void f(struct X*); };
class X {
    int i;
    friend void Y::f(X*);
};

还有什么建议?

此外,在按值传递时,您甚至不必具有完整类型,除非您实际定义了方法

struct Y { void f(struct X); };
// too early:    
void Y::f(struct X) { /* whoops compile error */ }
class X {
    int i;
    friend void Y::f(X);
};
// ok here:
void Y::f(X) { /* compile success */ }

毕竟,正如作者所指出的:"编译器总是知道如何传递一个固定大小的地址。这只是一个声明,告诉编译器 X 是一个结构体并且很快就会遵循,那么为什么编译器如此坚持要你输入字母:struct X;毕竟我没有使用 X 本身??此时没有生成汇编语言代码。当它读取"X*"时,它肯定可以说它是一个地址(指针)。为什么是:需要struct X;

作者并没有告诉你所有令人讨厌的细节。编译器知道如何传递指针(地址),如果它知道X是哪种对象。该语言允许某些指针(如指向可寻字机器上的char的指针或指向函数的指针)具有不同的大小。

因此,您必须告诉编译器X是内置类型的struct,而不是函数或 typedef。

相关文章: