【问题标题】:Programming language development practice, how to compile golang style interfaces to c++?编程语言开发实践,如何将golang风格的接口编译成c++?
【发布时间】:2020-07-23 08:53:27
【问题描述】:

为了好玩,我一直在研究我自己的编译成 C++ 的编程语言。虽然大多数东西打印起来都相当简单,但我在将我的 golang 样式接口编译为 c++ 时遇到了麻烦。在 golang 中,您不需要显式声明特定结构实现接口,如果结构具有在接口中声明的所有函数,它会自动发生。最初我打算将接口编译成一个包含所有虚拟方法的类

class MyInterface {
    public:
        void DoSomthing() = 0;
}

所有实现结构都可以像在 c++ 中一样简单地从接口扩展

class MyClass: public MyInterface {
    // ...
}

但是,这意味着我的编译器必须遍历源代码中定义的每个接口(以及所有依赖项)以及源代码中定义的每个结构,并检查结构是否使用需要执行的操作来实现接口O(N*M) 时间,其中 N 是结构的数量,M 是接口的数量。我做了一些搜索并在这里偶然发现了一些 c++ 代码:http://wall.org/~lewis/2012/07/23/go-style-interfaces-in-cpp.html 这使得 c++ 中的 golang 样式接口成为现实,在这种情况下,我可以将我的接口编译为类似的代码(尽管不完全是因为我犹豫使用原始指针通过智能指针),而不必担心显式地实现它们。然而,作者表示不应该为生产代码做这件事,这让我有点担心。

这是一个有点主观的问题,但是有更多 C++ 知识的人可以告诉我,如果按照文章中建议的方式进行操作是一个非常糟糕的主意,还是实际上并没有那么糟糕并且可以完成,或者是否有更好的方法来编写 c++ 代码,让我无需求助于 O(N*M) 循环即可实现我想要的行为?

【问题讨论】:

标签: c++ compiler-construction code-generation


【解决方案1】:

我最初的想法是利用 C++ 支持多重继承这一事实。将您的 golang 接口分解为单功能接口。通过其唯一签名对所有接口进行哈希处理。现在它变成了一个 O(N) 操作来为你的具体类找到一组 C++ 抽象接口。

同样,当你消费一个对象时,你会找到所有消费的接口。现在按相同的逻辑是 O(M)。然后总编译器复杂度变为 O(N)+O(M) 而不是 O(N*M)。

轻微的缺点是您将在 C++ 中拥有 O(N) 个 vtable。如果某些接口总是组合在一起,其中一些可能会被合并。

【讨论】:

  • 多重继承引入了菱形问题,如果两个接口有一些相同的方法(如果冲突的方法都是纯虚拟的),c++编译器将如何处理实现两个接口的类
  • @Hals:虚拟基类;该接口无论如何都没有 ctor 或数据。
猜你喜欢
  • 2016-12-21
  • 1970-01-01
  • 2011-04-30
  • 2011-09-23
  • 1970-01-01
  • 2010-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多