Jus*_*rey 2 fortran gfortran fortran77
我是Fortran的新手.请看下面的代码:
c main program
call foo(2)
print*, 2
stop
end
subroutine foo(x)
x = x + 1
return
end
Run Code Online (Sandbox Code Playgroud)
非常感谢帮助.谢谢.
该程序打破了语言规则 - x子程序中的伪参数通过线修改x = x + 1,但它与表达式(简单常量)相关联.通常,无法修改由表达式生成的值.
该特定代码在语法上仍然有效Fortran 2008.它仍然是Fortran 2008中的编程错误 - 就像在Fortran IV/66中一样.这不是编译器需要诊断的东西.有些人可能会使用额外的调试选项,也可能直到运行时.
因为程序会破坏语言规则,所以当您运行程序时可能会发生任何事情.究竟是什么取决于编译器生成的代码.编译器可能为表达式产生的值留出了可修改的存储空间,使得它在内部看起来像一个变量(程序可能打印三个并且程序继续执行),可修改的存储可能在整个程序中共享,用于其他实例.常量2(突然2变成三个值到处都是!),常量值的存储可能在不可修改的内存中(程序可能会崩溃),编译器可能会发出错误消息,程序可能会生气并生气卧室,该计划可能会宣布对邻国的战争 - 这是一个编程错误 - 发生的事情是未指明的.
从Fortran 90开始,设备被引入到语言中,以允许程序员编写新的代码,编译器可以检查这些错误(在某些情况下,编译器需要检查错误,如果它们被视为标准错误符合).
对于所显示的代码,主程序和子程序应被视为单独编译 - 主程序不知道子程序的细节,反之亦然(子程序可能在主程序之后很长时间编译,在另一台机器上,两者的输出在稍后阶段被链接在一起 - 没有花哨的链接时间行为或静态分析,因此不可能解决诸如此类的错误.语言规则是这样的,当编译主程序时,编译器必须仅基于引用子例程的方式隐式地假设子例程的接口的细节 - 在主程序内子例程具有隐式接口.
Fortran 90引入了显式接口的概念,其中编译器以各种方式明确地告知子例程的接口,然后可以检查对子例程的任何引用是否与该接口一致.如果过程是模块过程,内部过程或内部过程 - 该接口自动实现,或者对于外部子程序,过程指针等,程序员可以使用接口块显式地描述接口.
此外,Fortran 90引入了intent属性 - 一个过程的伪参数的特征,这也是过程接口的特征.参数的意图向编译器指示过程是否可以定义参数(它也可能对默认初始化和组件分配状态有影响),因此表达式是否可以是有效的实际参数. x在子程序中foo通常会声明为INTENT(INOUT).
总的来说,当使用具有基本实现质量水平的编译器时,这些新语言功能可以有效抵御这种编程错误.如果您从该语言开始,那么建议这些新功能成为您的标准方法的一部分 - 即使用隐式none,所有过程通常应该是模块过程或内部过程,仅在绝对需要时使用外部过程,始终指定伪参数意图,使用自由形式的来源.