英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论