Nor*_*ico 16 fortran module include
使用带use声明的模块或带声明的隔离文件有什么实际区别include?我的意思是,如果我有一个使用了很多在整个程序中的子程序:当或为什么我应该把它放在一个模块内部或者只是把它写在一个单独的文件,包括它在它需要程序的所有其他部分用过的?
另外,将所有子程序写入单独文件中的模块并include在模块内使用是不是一个好习惯?特别是如果在子程序的代码很长,这样才能保持代码组织得更好(这样子程序都装在国防部,但如果我有编辑一个我并不需要去虽然代码迷宫).
Ian*_*anH 23
两者之间的概念差异映射到非常显着的实际差异.
INCLUDE行在源级别运行 - 它实现简单("哑")文本包含.在包含行中没有任何特殊的处理器解释"文件名"(实际上不需要文件)的情况下,完整的源代码可以很容易地由程序员手动拼接在一起并送到编译器而没有区别 - 在源语义中也是如此.包含的源没有孤立的真实解释 - 它的含义完全取决于引用包含源的包含行的上下文.
模块在程序的更高实体级别运行,即在编译器正在考虑源实际描述的事物的级别.模块可以独立于其下游用户进行编译,一旦编译完成,编译器就可以准确地知道模块可以为程序提供哪些内容.
通常,使用包含行的人希望做的是实际设计的模块.
示例问题:
因为实体声明可以分布在多个语句中,所包含的源描述的实体可能不是您所期望的.考虑包含以下来源:
INTEGER :: i
在单独的情况下,它看起来像是将名称声明i为整数标量(或者可能是函数?谁知道!).现在考虑包括以上内容的以下范围:
INCLUDE "source from above"
DIMENSION :: i(10,10)
i现在是排名第二的阵列!也许你想让它成为一个指针?可分配?一个虚拟的论点?也许这会导致错误,或者它可能是有效的来源!将隐式打字投入到混音中以真正增加潜在的乐趣.
模块中定义的实体由模块"完全"定义.可以更改特定于使用范围的属性(VOLATILE,可访问性等),但基本实体保持不变.名称冲突被明确调出,可以在USE语句中使用重命名子句轻松解决.
Fortran对语句排序有限制(规范语句必须在可执行语句之前进行,等等).包含的来源也受到这些限制,同样在包含点的背景下,而不是源定义的点.
在语句功能定义(规范部分)和赋值语句(可执行部分)之间很好地混合了一些完全钝的错误消息,或者更糟糕的是,编译器默认接受错误的代码.
有关引用模块的USE语句出现位置的要求,但实际模块程序单元的源完全独立于其使用点.
想要在相关程序中共享一些全局状态,并且想要使用include吗?让我向您介绍常见的块和序列关联的相关基础概念......
序列关联是早期底层Fortran处理器实现的一个不幸的漏洞,这是一个容易出错,不灵活,反优化的时代错误.
模块变量使公共块及其相关的邪恶完全不必要.
如果您使用的是include行,请注意您实际上并未包含常用过程的来源(第一段中的建议只会导致编译器出现语法错误).您通常要做的是包含描述过程接口的源.对于任何非平凡的过程,描述接口的源与过程的完整源不同 - 暗示您现在需要维护同一事物的两个源表示.这是一个容易出错的维护负担.
如上所述 - 编译器自动获得模块过程接口的知识(编译器知识是"显式的",因为它实际上看到了过程的代码 - 因此称为"显式接口").程序员不需要做更多的事情.
上述结果是外部子程序根本不应该被使用,除非有充分的理由相反(可能存在循环或过度广泛的依赖) - 基本出发点应该是将所有内容放在模块或主要模块中程序.
其他海报提到了模块的源代码组织优势 - 包括将相关程序和其他"东西"分组到一个包中的能力,并控制内部实现细节的可访问性.
我接受根据问题的第二段有效使用INCLUDE行 - 大型模块的大小变得难以处理.F2008通过子模块解决了这个问题,这也带来了许多其他好处.一旦它们得到广泛支持,就应该放弃包含线的解决方案.
第二个有效用途是克服通用编程技术(C++中提供的模板)的语言缺乏支持 - 即操作中涉及的对象类型可能有所不同,但描述如何处理这些操作的令牌序列对象基本相同.在语言对其进行排序之前,可能还需要十年左右的时间.
将过程放入模块并使用这些模块使过程的接口显式化.它允许Fortran编译器检查调用中的实际参数与过程的伪参数之间的一致性.这可以防止各种程序员的错误.Fortran> = 90的某些"高级"功能也需要显式接口; 例如,可选或关键字参数.如果没有显式接口,编译器将不会生成正确的调用.仅包括文件不提供这些优点.
MSB 的答案很好,这可能是更喜欢模块而不是包含的最重要原因。我想补充一些想法。
如果这对您很重要,那么使用模块可以减少编译后的二进制文件的大小。模块被编译一次,当您use编译时,您就象征性地加载该模块以使用代码。当您include创建文件时,您实际上是将新代码插入到您的例程中。如果您使用include大量,可能会导致您的二进制文件很大并且还会增加编译时间。
您还可以通过巧妙地使用模块中的公共和私有函数以及用户定义的类型,使用模块在 Fortran 90 中伪造 OOP 风格编码。即使您不想这样做,它也提供了一种很好的方法来对逻辑上属于在一起的函数进行分组。
| 归档时间: |
|
| 查看次数: |
13095 次 |
| 最近记录: |