本地初始化变量规则是否也适用于指针?

时间:2014-01-30 17:54:52

标签: fortran fortran90 gfortran fortran95

我知道在初始化本地声明的变量(reference)时应该小心。

!这是错误的方式 (声明时初始化的局部变量具有隐式保存属性。)

     real function kinetic_energy(v)
     real, dimension(:), intent(in) :: v
     real :: ke = 0.0
     end function kinetic_energy

!这是正确的方式

     real function kinetic_energy(v)
     real, dimension(:), intent(in) :: v
     real :: ke
     ke = 0.
     end function kinetic_energy

我想知道我们是否也有这样的指针用于指针。

     real function kinetic_energy(v)
     real, dimension(:), intent(in) :: v
     real, pointer :: ke => null()
     end function kinetic_energy

     real function kinetic_energy(v)
     real, dimension(:), intent(in) :: v
     real, pointer :: ke
     nullify(ke)
     end function kinetic_energy

声明时被取消的指针变量将被视为保存属性!

感谢您提供有用的信息。我已经读过,总是将指针初始化为NULL,根据你所说的这可能是完全错误的语句。例如,我不应该在我的子例程中初始化我的本地指针变量! (如果在子程序的每个条目中将它们分配给新的大小)我是对的!!!

 real function kinetic_energy(v)   
 real, dimension(:), intent(in) :: v   
 !local variables
 real, dimension(:), pointer :: ke => null()
 integer :: n
 !
 n=size(v,1)   
 allocate(ke(n))   
 !make a copy   
 ke=v   
 !do some computation ...   
 end function kinetic_energy

2 个答案:

答案 0 :(得分:3)

指针和非指针的情况实际上几乎相同。 @francescalus是正确的,规则5.3.16.1确实谈到指针目标变得不确定的可能性,但这里并不重要。当然,如果保存的指针指向一些短暂的东西,那么在目标不再存在后它将无效,但这是非常明显的。

但是显式初始化的语义对于指针和非指针是相同的。它隐含save属性。这意味着在过程调用之间保留值或指针关联,因此初始化只执行一次(版本1和3)。如果要在每个过程调用时分配所需的值,则必须使用正常的可执行分配,而不是显式初始化表达式或其他可执行语句(版本2和版本4)。


修改

关于您的新(上一个)示例,这似乎是一个使用allocatable代替pointer的地方。它们永远不会被定义,但从not allocated开始。

如果您需要它作为指针,如果不测试其关联状态,则必须在分配之前不必使其无效。您始终可以在可执行代码的开头使用nullify()

答案 1 :(得分:1)

F2008标准中引用隐式SAVE属性的部分(5.2.3)不区分POINTER或不{ - 1}}的情况。

顺便说一句,虽然指针将获取属性,但指针POINTER意味着略有不同:

  

[...]除非它是指针并且其目标变为未定义

请参阅@ VladimirF的答案(这促使我在此澄清)了解更多信息。但是请注意,错误地认为空值初始化的指针在范围的每个条目上都是无效的,这可能比认为变量每次都分配为零更糟糕:如果SAVE只是测试ASSOCIATED(ke)是非标准的有未定义的指针关联状态。

回到你的例子,你的错误方式是“错误的方式”和“正确的方式”:“错误的方式”是正确的初始化方式,“正确的方式”是错误的初始化方式。也就是说,只有在第一种情况下才会发生任何初始化。

在问题更新后编辑:

具有ke属性的变量与没有初始化时的变量没有区别:如果变量具有显式初始化,则它获取pointer属性。如果您希望变量不具有此属性,则无法显式初始化它。 [这是对原始问题的一个比我之前更明确的答案。]

有关于总是“初始化”指针的建议。用MR& C的话来说,他们一般都有很好的建议:

  

我们建议所有指针都要初始化,以减少意外使用未定义指针造成奇怪影响的风险。在编写避免内存泄漏的代码时,这也是一种帮助。

这里的“初始化”确实包括“在子程序中早期无效”以及显式初始化。

但是,这不是必需的。如果指针要与其他东西相关联,则首先不需要(但可以)使其无效。即使是好的建议也不是避免小心的借口。

但它仍然有效,如果save不好,那么显式初始化就不好了。

此外,您可能会看到有关它具有默认初始化的派生类型的指针组件的建议。这是明智的建议。