Fortran为什么不为独立的子例程/函数创建显式接口?

huangapple go评论51阅读模式
英文:

Why Fortran does not create explicit interfaces for stand-alone subroutines/functions?

问题

使用子例程并允许编译器检查参数不匹配,需要将该子例程的定义放在一个模块中,因为在这种情况下,Fortran会为调用单元创建一个显式接口,以检查参数不匹配等。

对于不包含在模块中的独立子例程,我们称它们只有"隐式接口"而没有"显式接口",因此编译器无法检查参数不匹配。
为什么编译器不为独立子例程创建"显式接口"呢?是什么困难阻止编译器这样做?

英文:

To use a subroutine and allow the compiler to check
argument mismatch, one needs to place the defintion of that subroutine in a module, for which case, fortan creates an explicit interface for the calling unit to check argumetn mismatch etc.

For stand-alone subroutines that are not contained in a module, we say they have only "implicit interfaces" and no "explicit interfaces", so that the compiler can not check argument mismatch.
Why does not the compiler also create "explicit interfaces" for the stand-alone subroutines? What difficulties prevent the compiler from doing this?

答案1

得分: 1

这只是语言工作的方式,自上世纪50年代的创立以来一直都是这样的,首次标准化是在1960年代。

当时几乎没有其他选择,尽管一些其他语言,如Algol 68,或稍后的Modula,在十年多后才开始使用模块。例如,Pascal依赖于嵌套。

请注意,模块是一个相对较新的东西。C++直到几年前才引入了它们。否则,C(和C++)过去是通过包括文件来让编译器看到其他源文件的头文件,将所有内容包括到当前文件中。但在原始C中,也有隐式接口的选项。

在Fortran中,编译单元是个别的程序单元,而不是源文件。可以编写或甚至自动生成接口块(例如,评论中提到的-gen-interfaces编译器选项)并使用包含文件将它们包含进来,但这种方法很少被推荐。

尽管在没有模块或包含头文件的情况下理论上可以使用显式接口的概念,但在传统编译语言的编程世界中并没有太多这样的概念。

显式接口的概念是在Fortran 1990中引入的。它允许以一些新的方式调用更高级的Fortran子程序(如数组结果、假设形状、可选参数等)。但它也允许进行以前不可能的检查。强制执行这些检查会破坏现有的代码。成功(或失败)在很大程度上也基于向后兼容性。不能破坏现有的代码太多 - 这将是很多工作。

编译器现在通常会警告您正在执行不允许的操作,如果您允许此类警告并启用或不禁用此类警告,则会提示外部子程序的调用不符合规范。但它始终只是一个警告,并不会为您带来新的可能性。遗留代码仍然可以正常工作。

这些警告也可能在链接阶段出现,特别是在使用链接时优化时。

英文:

It simply the way the language works and have always worked since the inception in the 1950s and first standardization in 1960s.

It had little other choice back then, even though some other languages like Algol 68, or later Modula, pioneered the use of modules a decade or more later. Pascal, for example, relied on nesting.

Mind you, modules are a relatively new thing. C++ got them only a few years ago. Otherwise C (and C++) used to include files to allow the compiler to see headers from other source files by including everything into the current file. But implicit interfaces were also an option in original C.

In Fortran, the compilation units are individual program units, not source files. One can write or even automatically generate (e.g. the -gen-interfaces compiler option mentioned in the comments) interface blocks and include them using include files, but this approach is rarely recommendable.

Even though explicit interfaces would theoretically theoretically be possible without modules or included headers, such a concept does not really exist much in the programming world for traditional compiled languages.

The concept of explicit interface was introduced in Fortran 1990. It allows some new ways of calling more advanced forms of Fortran subprograms (array results, assumed shape, optional arguments,...). However it also allows checks that were not possible before. Enforcing such checks would break existing code. The success (and its lack) is to a large extent also based on backward compatibility. You cannot brake existing code so much - it would really be a lot.

Compilers will now often warn you that you are doing something not allowed, that the call of an external subprogram is not conforming, if you allow such warnings and if you enable or do not disable such warnings. But it will always remain a warning and it does not bring you the new possibilities. Legacy codes remain working.

These warnings are also possible at the linking stage, especially when link-time optimizations are used.

答案2

得分: 1

以下是您要翻译的部分:

When we are considering interfaces, we are not talking about some mythical object which may be implicit or explicit.

Consider the two main programs:

These two main programs are (perhaps) concerned about the same external subroutine sub. main1 has an implicit interface for sub and main2 has an explicit interface for sub.

Whichever main program we are wondering about, the subroutine sub always has an explicit interface for itself:

I've just defined a (pretty terrible) subroutine called sub. I imagine that's going to be a popular name: next time you want to use that name (don't forget: external procedures are global entities) for an external procedure are you going to use the one I've just defined? If you aren't, how are you going to tell the compiler which sub you are talking about?

Resolution of which external subroutine sub is going to be used is often a problem for the linker, not the compiler. The compiler may never see a particular external procedure so cannot automatically generate for a program unit an explicit interface for an external procedure.

That said, there are cases where a compiler will do some work for you:

(as a single file, or separate files, perhaps with specific compiling options) may well prompt your compiler to complain, just as though sub had an explicit interface inside main3.

1 An external procedure can also be defined by means other than Fortran. In such a case, the Fortran compiler doesn't need to even understand it, let alone worry about having to generate an explicit interface for it.

英文:

When we are considering interfaces, we are not talking about some mythical object which may be implicit or explicit.

Consider the two main programs:

program main1
  implicit none (external)

  external sub

  call sub
end program main1

and

program main2
  implicit none (external)

  interface
    subroutine sub()
    end subroutine sub
  end interface

  call sub
end program main2

These two main programs are (perhaps) concerned about the same external subroutine sub. main1 has an implicit interface for sub and main2 has an explicit interface for sub.

Whichever main program we are wondering about, the subroutine sub always has an explicit interface for itself:

subroutine sub()
  implicit none (external)

  call sub
end subroutine sub

I've just defined a (pretty terrible) subroutine called sub. I imagine that's going to be a popular name: next time you want to use that name (don't forget: external procedures are global entities) for an external procedure are you going to use the one I've just defined? If you aren't, how are you going to tell the compiler which sub you are talking about?

Resolution of which external subroutine sub is going to be used is often a problem for the linker, not the compiler. The compiler may never see a particular external procedure so cannot automatically generate for a program unit an explicit interface for an external procedure.<sup>1</sup>

That said, there are cases where a compiler will do some work for you:

program main3
  implicit none (external)

  external sub
  
  call sub
end program main3

subroutine sub(x)
  implicit none (external)
  real x
end subroutine sub

(as a single file, or separate files, perhaps with specific compiling options) may well prompt your compiler to complain, just as though sub had an explicit interface inside main3.


<sup>1</sup> An external procedure can also be defined by means other than Fortran. In such a case, the Fortran compiler doesn't need to even understand it, let alone worry about having to generate an explicit interface for it.

huangapple
  • 本文由 发表于 2023年2月6日 11:08:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/75357011.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定