Compiler construction 解析外部模块中的函数类型

Compiler construction 解析外部模块中的函数类型,compiler-construction,module,programming-languages,static-typing,Compiler Construction,Module,Programming Languages,Static Typing,假设我们有一种虚构的静态类型编程语言——让我们称之为SL。每个SL文件对应于一个模块——SL将相关函数逻辑分组到名称空间中 对当前模块中函数的调用很容易检查:编译器过程发现所有声明的函数并存储它们的签名。稍后,我们可以通过比较参数类型和签名中的形式参数类型来验证任何此类调用 然而,处理对其他模块中函数的调用似乎要复杂一些。特别是,假设编译器可以找到与导入模块名称对应的源/目标代码,那么它如何提取类型信息?它是否: 扫描并解析导入模块的源代码,直到找到函数声明 从对象文件中读取某种元数据 在符号

假设我们有一种虚构的静态类型编程语言——让我们称之为SL。每个SL文件对应于一个模块——SL将相关函数逻辑分组到名称空间中

对当前模块中函数的调用很容易检查:编译器过程发现所有声明的函数并存储它们的签名。稍后,我们可以通过比较参数类型和签名中的形式参数类型来验证任何此类调用

然而,处理对其他模块中函数的调用似乎要复杂一些。特别是,假设编译器可以找到与导入模块名称对应的源/目标代码,那么它如何提取类型信息?它是否:

  • 扫描并解析导入模块的源代码,直到找到函数声明
  • 从对象文件中读取某种元数据
  • 在符号名称中编码函数返回类型和参数类型,并在编译时读取符号表
  • 在别处找到元数据
我很好奇现代语言(如Haskell、D和Go)的编译器采用什么方法



<>编辑:我知道C和C++使用头文件解决这个问题。我对这种方法不感兴趣。理想情况下,我正在寻找一种根本不涉及任何解析的解决方案。

这就是为什么c/c++需要一个头文件来包含一个静态库或dll。对于dll,您只能通过检查dll来了解函数。这意味着dll文件存储函数名、返回值和参数类型。有一些工具可以生成这种声明

实际上,你给出了问题的答案。根据情况使用所有方法

从对象文件中读取某种元数据

对于动态库(如DLL),您可以动态查询对象代码并通过函数指针调用它。免费 所以是的。net语言,比如c#,vb经常使用这个

在别处找到元数据

对于C/C++来说,如果使用静态库,则需要一个用于定义的头文件。我不能举例说明你说的语言

扫描并解析导入模块的源代码,直到找到函数声明

如果你有代码,这是一种明显的方法,就像你有其他代码一样


我认为Go、D或Haskell与C/C++没有什么不同

这就是为什么c/c++需要包含静态库或dll的头文件。对于dll,您只能通过检查dll来了解函数。这意味着dll文件存储函数名、返回值和参数类型。有一些工具可以生成这种声明

实际上,你给出了问题的答案。根据情况使用所有方法

从对象文件中读取某种元数据

对于动态库(如DLL),您可以动态查询对象代码并通过函数指针调用它。免费 所以是的。net语言,比如c#,vb经常使用这个

在别处找到元数据

对于C/C++来说,如果使用静态库,则需要一个用于定义的头文件。我不能举例说明你说的语言

扫描并解析导入模块的源代码,直到找到函数声明

如果你有代码,这是一种明显的方法,就像你有其他代码一样


我认为Go、D或Haskell与C/C++没有什么不同

首先,请注意,这种类型解析是编译器的属性,而不是语言本身。C/C++的不同实现实际上提供了不同的特性,例如Microsoft的“预编译头”选项


Haskell的GHC编译器通过生成包含必要类型信息的接口文件(带有“.hi”后缀)来处理此问题。我想这就是“在别处查找元数据”。

首先,请注意,这种类型解析是编译器的属性,而不是语言本身。C/C++的不同实现实际上提供了不同的特性,例如Microsoft的“预编译头”选项


Haskell的GHC编译器通过生成包含必要类型信息的接口文件(带有“.hi”后缀)来处理此问题。我想这有资格“在别处找到元数据”。对不起,我应该补充说,我很清楚C和C++是如何解决这个问题的。(后期编辑)我想要解释的是像Go这样的语言如何在编译时发现其他模块/包导出的函数类型,即不将其留给链接器。对于静态类型的语言,函数类型应该在编译时确定。即使对于DLL,你也应该有编译的声明(尽管给出错误的声明是可能的,这会导致混乱的运行时问题)为什么你要从其他语言中分离C++。因为没有“现代”?因为它没有真正的模块,例如Haskell,抱歉,我应该补充说,我很清楚C和C++是如何解决这个问题的。(后期编辑)我想要解释的是像Go这样的语言如何在编译时发现其他模块/包导出的函数类型,即不将其留给链接器。对于静态类型的语言,函数类型应该在编译时确定。即使对于DLL,你也应该有编译的声明(尽管给出错误的声明是可能的,这会导致混乱的运行时问题)为什么你要从其他语言中分离C++。因为它不是“现代的”?因为它实际上没有像Haskell那样的模块。你在寻找与pragma相同的功能吗?或者类似的?没什么特别的-我只是想知道如何确定e的类型