Linker 在哪种情况下允许C编译器忽略调用约定?
出于显而易见的原因,C编译器必须编译其他共享库在外部可见的所有函数,以便它们符合平台的调用约定和其他ABI要求。但是,我了解到,对于可以保证永远不会从外部模块调用的函数,不一定需要这样做 编译器如何以及何时才能确定给定函数是否为真Linker 在哪种情况下允许C编译器忽略调用约定?,linker,shared-libraries,calling-convention,abi,Linker,Shared Libraries,Calling Convention,Abi,出于显而易见的原因,C编译器必须编译其他共享库在外部可见的所有函数,以便它们符合平台的调用约定和其他ABI要求。但是,我了解到,对于可以保证永远不会从外部模块调用的函数,不一定需要这样做 编译器如何以及何时才能确定给定函数是否为真 静态函数仅对同一编译单元中的其他函数可见,因此,对于这种破坏ABI的优化来说,它是一个很好的候选者。但是指向静态函数的函数指针仍然可以传递给其他模块。编译器是否尝试确定函数指针是否在代码中的任何位置传递 gcc编译器具有允许将符号声明为默认、隐藏甚至内部的功能,文档
- 静态函数仅对同一编译单元中的其他函数可见,因此,对于这种破坏ABI的优化来说,它是一个很好的候选者。但是指向静态函数的函数指针仍然可以传递给其他模块。编译器是否尝试确定函数指针是否在代码中的任何位置传递
- gcc编译器具有允许将符号声明为默认、隐藏甚至内部的功能,文档中特别提到,这些信息可用于执行某些外部可见函数无法执行的优化。如果函数指针被传递给注释为内部函数的外部代码,会发生什么情况
除非您的库仅由一个翻译单元组成,否则您可能希望几乎所有函数都需要外部可见。在C语言中,“外部但仅在我的库中”和“所有外部”之间没有什么有意义的区别。然而,理论上,你可以试试这个。但是,我怀疑您是否能获得很大的加速,对于一个非常重要的代码库来说,这将是一项艰巨的工作。在某些ARM系统上,如果代码期望浮点值以与其他参数相同的方式传递,或者在FP寄存器中传递,则可能会存在兼容性困难。如果不是函数指针,我认为这个问题可以通过使用FPU生成代码的编译器来解决,该编译器使用FPU寄存器和“弱链接”生成一个名称有误的函数版本具有未损坏名称的包装器,该包装器将普通参数复制到FPU寄存器并调用损坏的命名版本。使用FPU并希望调用FPU寄存器版本的编译器编译代码将生成对损坏名称版本的调用,以及一个弱链接的包装器,它将FPU寄存器复制到普通参数并调用未损坏的版本。这应该允许调用方和被调用代码FPU使用的任意组合之间的“通用”行为。至于函数指针,我认为人们可以通过说除非声明“特别”它们总是指向使用最基本ABI的方法来回避ABI差异的问题。这看起来可行吗?