我是否需要将implicit none
放在每个函数和子例程中?
或者将它放在包含这些函数和子程序的模块的开头是否足够?
或者将它放在使用这些模块的程序的开头就足够了吗?
通过观察其他人的工作代码,implicit none
包含在所有这些地方。我不确定这是否是冗余的,因为从子程序中删除implicit none
仍然编译并生成相同的输出。
顺便说一下,我正在使用gfortran fortran 90
。
答案 0 :(得分:22)
implicit
语句(包括implicit none
)适用于作用域单元。这样的事情被定义为
BLOCK构造,派生类型定义,接口主体,程序单元或子程序,不包括其中的所有嵌套作用域单元
这"排除其中所有嵌套的作用域单位"表明在模块中定义的每个函数和子例程(统称为过程)中可能需要/期望implicit none
。但是,在模块中包含的内部过程中,存在基于主机作用域单元的默认映射。因此,在模块中使用implicit none
时,无需在包含的过程中使用implicit none
。
此主机作用域单元规则同样适用于内部程序。这意味着主程序中的implicit
涵盖了其中包含的所有程序;这同样适用于模块程序的内部程序。阻止构造也会看到这一点,并且use
语句甚至不允许在其中一个语句中使用。
但是,外部函数/子例程不会从程序或模块继承隐式行为,并且模块不会从implicit none
use somemodule
end program
它们的程序/其他模块继承它。这显然是有道理的,因为隐式类型必须在编译时知道并且无论其最终用途如何都要明确定义。
此外,一个人做不到
implicit
use
语句必须遵循所有module mod
implicit none
interface
subroutine external_sub()
! The default implicit typing rules apply here unless there is an implicit
! statement, such as implicit none. Those from the module aren't in force here.
end subroutine
end interface
end module
语句。
此主机范围单元规则显然不适用于接口主体。 IanH's answer激发了这种例外,但重新压力是一件非常重要的事情。这引起了很大的困惑。
implicit none
关于从子例程中删除implicit none
的测试:如果代码对{{1}}有效,那么它必须是有效的且没有该语句的相同。必须在前一种情况下显式声明所有实体,因此后者不会应用任何隐式规则。
答案 1 :(得分:6)
不,是(有点)和否。
每个程序单元一次(这与每个程序不一样)并且在每个接口体中就足够了。
程序单元是主程序,模块,外部子程序(在其他类型的程序单元的CONTAINS语句之后不出现的函数或子程序子程序),块数据程序单元或子模块。除非使用IMPLICIT语句另行指定,否则每个程序单元中的默认值是以I-N作为默认整数开始的事物的默认映射,其他所有内容都默认为real。
同样的原则适用于接口主体 - 因为它们应该是另一个程序单元中定义的过程的规范部分的快照。除非另有说明,否则其他程序单元将具有默认映射,因此除非另有指定,否则接口主体具有默认映射。
在程序单元内部,内部子程序或模块子程序继承了在主机中指定的任何隐式类型,而没有" local"子程序中的IMPLICIT声明。
IMPLICIT NONE的冗余规范是无害的。您经常会看到以前外部子程序的子程序已放入模块中。
答案 2 :(得分:5)
这是一个基于对我有用的非正式答案。
我的Fortran代码有两种类型的文件 - 包含主程序和包含单个模块的文件。在每种文件中,IMPLICIT NONE出现在“program foo”或“module foo”语句之后以及顶部的USE语句之后。它不会出现在子程序或函数中,因为这将是多余的。
答案 3 :(得分:1)
如果您使用的是public class IteratorFailFastTest {
private List<Integer> list = new ArrayList<>();
public IteratorFailFastTest() {
for (int i = 0; i < 10; i++) {
list.add(i);
}
}
public void runUpdateThread() {
Thread thread2 = new Thread(new Runnable() {
public void run() {
for (int i = 10; i < 20; i++) {
list.add(i);
}
}
});
thread2.start();
}
public void runIteratorThread() {
Thread thread1 = new Thread(new Runnable() {
public void run() {
ListIterator<Integer> iterator = list.listIterator();
while (iterator.hasNext()) {
Integer number = iterator.next();
System.out.println(number);
}
}
});
thread1.start();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
IteratorFailFastTest tester = new IteratorFailFastTest();
tester.runIteratorThread();
tester.runUpdateThread();
}
}
,您也可以简单地添加-fimplicit-none
参数。
请注意,这是特定于编译器的解决方案。其他广泛的编译器可能不支持此参数。例如,英特尔gfortran
将此视为未知选项。