Fortran 预处理器指令用法

Posted

技术标签:

【中文标题】Fortran 预处理器指令用法【英文标题】:Fortran Preprocessor Directive Usage 【发布时间】:2015-09-29 16:56:17 【问题描述】:

好的,所以我可能会以不应该的方式使用某些东西,但这是我的问题。我正在尝试制作一个可以容纳扩展单个父类型的不同类型的数组。为此(通过这篇帖子https://software.intel.com/en-us/forums/topic/280765),建议我按照以下方式进行。

program main

implicit none

type shape
    integer :: x,y
end type shape

type shape_c
    class(shape), pointer :: s
end type shape_c

type, extends(shape) :: rectangle
    integer :: w,h
end type rectangle

type, extends(shape) :: circle
    integer :: r
end type

type(rectangle) :: r
type(circle) :: c
type(shape) :: s

class(shape_c), dimension(:), allocatable :: shapes

r = initRect()
c = initCircle()
s = initShape()

allocate(shapes(3))

shapes(1)%s => r
shapes(2)%s => c
shapes(3)%s => s

write(*,*) shapes(1)%s%x * shapes(2)%s%x * shapes(3)%s%x

end program main

在那篇文章的最后,有人建议我使用 fpp 以避免每次都在形状后写 '%s'。所以我尝试使用下面的程序 main.

#define shapes(m) shapes(m)%s

这当然很好用,除非 'allocate(shapes(3))' 会破坏代码。我不知道如何避免这种情况发生。

因此,可能的问题是,是否有更好的方法来处理继承变量的数​​组,避免在 allocate 语句期间中断的方法,或解决此问题的其他方法。此外,关于如何使用 fpp 的体面指南也会有所帮助。 https://software.intel.com/en-us/node/510271 是我目前正在使用的,如果我以前使用过预处理器,我确信它会有所帮助,但对于没有使用过预处理器的人来说并不是那么有用。

我正在使用 Intel Visual Fortran 2015 和 VS2012。

【问题讨论】:

为什么不在分配后定义宏? 出于多种原因。首先,据我所知,预处理器必须在声明变量之前定义很多要定义的东西。另一个是即使我可以在任何地方定义它,实际代码也比示例复杂得多,所以它并不像那样清晰。我想我可以写#define after 语句和#undef before 语句,但这听起来像是更糟糕的选择。 对不起,别介意不在别处定义。那是我的一个错字。其余的仍然存在。 【参考方案1】:

shapes(m)shapes(m)%s 在 Fortran 中都有意义,因此将所有 shapes(m) 重新定义为 shapes(m)%s 显然会破坏代码。定义宏时应该使用非 Fortran 关键字,或者至少使用其他地方不存在的词。例如,

#define SHAPES(m) shapes(m)%s

(通常在预处理器宏中使用大写字母)或者如果您坚持保存击键,则可以使用更短的内容。话虽如此,使用预处理器来缩短代码可能不是最好的样式,并且可能会损害可读性。我建议使用文本编辑器的功能来轻松插入相关代码位。

【讨论】:

是的,我同意 fpp 不是理想的方式。我刚刚意识到,如果我(或我团队中的其他人)写了正确的“shapes(1)%s%x”,它也会破坏代码。只是有那么多多余的代码(我从来没有真正想调用“shapes(1)”而不意味着“shapes(1)%s”)真的让我很困扰。看起来并不多,但是这个数组(非常)经常被访问,并且它下面有很多变量和派生类型,看起来这会进一步加剧混乱问题。如果预处理器处理某种形式的正则表达式,那将非常方便。 哦,是的。在制作示例时,我没有注意到我使用了 Fortran 关键字。真正的代码不使用关键字。不过,这不是导致中断的原因。 SHAPESshapes 在 Fortran 中是一样的,大小写无关紧要。这对预处理器很重要,但对读者来说仍然会让人感到困惑。 是的,但是看一下我假设代码只是小写或混合大小写的示例。如果是这样,那么我总是怀疑SHAPES 是一个预处理器关键字(也许它只是我)。为进一步避免混淆,还可以在关键字中添加一些下划线。 问题在于它使行“分配(形状(m)%s)”。似乎没有办法让预处理器足够聪明,只在某些情况下才这样做。或者我更喜欢一种更好的方法来完成我想要用继承做的事情。

以上是关于Fortran 预处理器指令用法的主要内容,如果未能解决你的问题,请参考以下文章

cmake可以自动添加fortran预处理器-cpp标志吗?

预处理器和使用关联

将 Fortran 转换为 C 或 C++

从 fortran 代码中清除预处理器条件

预处理器指令

预处理器指令