这位英特尔专家给出了解释和优雅的解决方案。我无法更好地解释它。完整引用如下:
“有一天,当我在当地杂货店的过道上闲逛时,一位女士把我招到一张桌子旁,问我想不想‘尝尝进口巧克力? ... 吉拉德利?我问那个女人,加利福尼亚是否已经脱离联邦,因为吉拉德利,尽管它的意大利名字,来自旧金山。我想从新罕布什尔州的有利位置来看,加利福尼亚还不如成为另一个国家,很多正如著名的索尔·斯坦伯格 1976 年《纽约客》封面“第 9 大道的世界观”中所描绘的那样。
(有人警告我,我的博客没有足够的任意链接——这应该会保留一段时间。)
同样,在 Fortran 中(我敢打赌你想知道我什么时候能做到这一点),有些东西可能如此接近,但看起来却如此遥远。不久前,我正在为英特尔 Visual Fortran 编写一个新模块,为 Win32 进程状态 API 提供声明。这将包含类型和常量的声明以及 API 例程的接口块,其中一些接受新类型的参数。自然的倾向是这样写:
MODULE psapi
TYPE sometype
some component
END TYPE sometype
INTERFACE
FUNCTION newroutine (arg)
INTEGER :: newroutine
TYPE (sometype) :: arg
END FUNCTION newroutine
END INTERFACE
END MODULE psapi
如果你这样做并编译了它,你会得到一个错误,即类型 sometype 在 arg 的声明中未定义。“什么?不是未申报,在同一个模块上面我可以看到!” 嗯,是的,也不是。是的,它是在模块中声明的,并且可以在模块中的任何地方使用,除了.. 除了在接口块中!
问题是接口块是“外部例程的窗口”——假设例程是用 Fortran 编写的,它们基本上复制了您在实际外部例程中看到的声明。因此,它们不会“宿主关联”来自封闭范围单元(本例中的模块)的任何符号。
在 Fortran 90 和 Fortran 95 中,典型的解决方案是创建一个单独的模块,比如“psapi_types”,其中包含要使用的所有类型和常量,然后在每个函数中添加一个 USE 语句,就像您将不得不在用 Fortran 编写的假设外部例程中。(如果它是用 Fortran 编写的,Doctor 会用湿打孔卡拍打你的手腕,并告诉你把例程变成一个模块过程,然后你就不用担心这种胡说八道了。)所以你最终会得到一些东西像这样:
MODULE psapi
USE psapi_types ! This is for the benefit of users of module psapi
INTERFACE
FUNCTION newroutine (arg)
USE psapi_types
INTEGER :: newroutine
TYPE (sometype) :: arg
...
使用 Intel Visual Fortran 的人都知道,事实上有一个巨大的模块 IFWINTY 用于此目的,其中包含其他 Win32 API 的所有类型和常量。这是凌乱和不雅的,但这是你必须做的。到现在...
Fortran 2003 试图为这种令人遗憾的情况恢复一些优雅,但为了保持与旧源的兼容性,它不能仅仅声明接口块参与主机关联。相反,创建了一个新语句 IMPORT。IMPORT 只允许出现在接口块中,它告诉编译器导入主机范围内可见的名称。
IMPORT 放在任何 USE 语句之后,但在接口主体(FUNCTION 或 SUBROUTINE 声明)中的任何 IMPLICIT 语句之前。IMPORT 可以有一个可选的 import-name-list,很像 USE。没有一个,主机中可访问的所有实体在接口主体内都变得可见。使用列表,只有命名实体是可见的。
使用 IMPORT,我的 PSAPI 模块可以看起来像第一个示例,但有以下更改:
...
FUNCTION newroutine (arg)
IMPORT
INTEGER :: newroutine
TYPE(sometype) :: arg
...
如果我愿意,我可以使用:
IMPORT :: sometype
说我只想要一个进口的名字。漂亮整洁,集中在一个模块中!
“但你为什么要告诉我这个?”,您可能会问,“这是 Fortran 2003 的一个特性,而英特尔 Fortran 还没有完成 Fortran 2003 的所有功能。” 确实如此,但我们不断向编译器添加越来越多的 F2003 功能,并且 IMPORT 早在 8 月就实现了!因此,如果您保持合理的最新状态,您现在可以随心所欲地导入,并消除为您的类型和常量使用单独模块的混乱。
如果您想知道还有哪些其他 F2003 好东西可供您使用,只需查看每个更新的发行说明。每个问题都提供了受支持的 F2003 功能的完整列表。把它们都收集起来!”