Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Pointers 为什么Fortran指针总是可变的_Pointers_Fortran_Constants - Fatal编程技术网

Pointers 为什么Fortran指针总是可变的

Pointers 为什么Fortran指针总是可变的,pointers,fortran,constants,Pointers,Fortran,Constants,我刚开始使用Fortran中的指针,最近偶然发现了一个事实,Fortran中的指针不能是常量。这意味着,这样的事情是不可能的: procedure(proc_type), pointer, parameter :: fPtr => myFunc 我试图找出这不可能的原因。但我唯一发现的是“现代Fortran解释”: 还要注意,常数可能不是指针[…],因为它们是 总是变量 但这并不能解释背后的原因。有人知道吗?因为Fortran规则是这么说的 Fortran 2008(ISO/IEC 15

我刚开始使用Fortran中的指针,最近偶然发现了一个事实,Fortran中的指针不能是常量。这意味着,这样的事情是不可能的:

procedure(proc_type), pointer, parameter :: fPtr => myFunc
我试图找出这不可能的原因。但我唯一发现的是“现代Fortran解释”:

还要注意,常数可能不是指针[…],因为它们是 总是变量


但这并不能解释背后的原因。有人知道吗?

因为Fortran规则是这么说的

Fortran 2008(ISO/IEC 1539-1-2010):

5.3.14指针属性

1具有指针属性的实体可以在执行期间与不同的数据对象或过程相关联 一个程序的名称。指针是数据指针或过程 指针。中介绍了过程指针 12.4.3.6

这与常量不兼容

为什么规则是这样的?因为该标准的作者这样做了

他们为什么那样做?答案通常非常简单——因为没有人提出不同的规则供委员会讨论和批准,或者委员会的一些成员不喜欢。你真的必须问他们,但是要准备好回答,没有具体的原因

在属于同一类的一些语言中,例如C和C++,可以使用常数指针。初始化为指向整型常量的常量指针

const int i = 3;
static int* const x=(int*)&i;
初始化为指向整数函数的常量指针

int fun(){
  return 1;
}

static int (* const x)()=&fun;
在Fortran中,这样的东西肯定是可以允许的。请与Fortran标准委员会中的代表联系,提出此类功能的建议


正如IanH和credondo所示,有一些方法可以绕过这个限制,但是这个答案试图保持原始问题的路线。为什么存在此限制?

如果指针在具有
PROTECTED
属性的模块内声明,则指针在该模块外变为常量(编辑:)

module mod1
  implicit none
  procedure()                     :: p_target
  procedure(), pointer            :: ptr => null()
  procedure(), pointer, protected :: ptr_protected => null()
end module mod1


program pointer_parameter
  USE mod1
  implicit none
  ptr            => p_target        
  ptr_protected  => p_target
end program
编译器返回以下错误

gfortran -c pointer_parameter.f90
pointer_parameter.f90:6.3:

ptr_protected  => p_target
1
Error: Variable 'ptr_protected' is PROTECTED and can not appear in a pointer
association context (pointer assignment) at (1)

这取决于“常量指针”的含义

如果您指的是一个指针对象,其关联状态在程序执行期间无法更改,那么您的前提是false。。。您可以声明和初始化其关联状态在程序执行期间无法更改的指针对象

TYPE :: t
  PROCEDURE(xyz), POINTER :: fPtr
END TYPE t

TYPE(t), PARAMETER :: this_a_constant = t(myFunc)
数据对象也有类似的功能。您可以使用组件的默认初始化来实现类似的结果

如果在指向数据对象的指针的情况下,您指的是指向常量的对象,那么直接的解释是Fortran中的命名常量(和文字常量)表示值,值不能是目标,并且只能将指针与目标关联。在这一直接解释的背后是实现视角,即该值在运行时可能实际上不需要存在,因此可能不会为其留出存储空间,因此从实现角度来看,没有什么值得指出的。将来,我想您可以围绕此更改语言规则,以便命名常量也可以具有target属性,但是如果不在其他地方产生问题,那么这种更改的规范可能非常困难


这两个方面的一个共同点是,孤立指针的关联状态不是所指向对象的值的一部分,但对象指针组件的指针关联状态是该对象值的一部分。

谢谢。这证实了我的怀疑,这不是由于技术原因,例如类型系统。在C和C++中,你可以有<代码>静态int *const < /C> >,所以可以很容易地为FORTRAN编上类似的东西。我猜在函数指针上会更复杂,对吧?再次,<代码>静态int(*const x)()<代码> >因此,可以为Fortran提出一些等价物。这在技术上是可能的,它并不是一个常数。它不能在模块外部更改,但可以在模块内部更改。如果寻找一个常量指针的重要原因是为了阻止程序的其他部分改变它的值,那么将它封装在一个模块中就是绕过语言规范中的障碍的一步。除了修改规范,没有完全语言支持的规范是人们唯一可以编写代码的“常量指针”。不幸的是,它很容易变异,不是一种很强的保护。但更重要的是,你的问题是为什么Fortran语言中存在限制,而不是如何规避限制。对于过程指针@VladimirF comment,“可以使用指针或类似技巧进行更改”是不相关的-指针只能指向目标,而不能指向其他指针,并且不能使过程指针的目标在标准语言的范围内消失。对于指向数据对象的指针,有可能通过不同的指针或可分配对象取消分配目标(假设它最初是使用allocate创建的),但在这种情况下,对受保护指针的指针关联状态的影响是非常间接的。这样,您就有了一个不合格的程序。用一个普通的命名常量做一些等价的事情也很简单,注意MFE中的语句已经过时了。过程指针不是变量。@IanH您能详细说明一下吗?是否有更多关于过程指针的信息?在日常口语中使用“变量”和正式语言定义(在标准中)之间有区别。在形式意义上,变量(和常量)是数据对象。过程不是数据对象。MFE的这一部分早于F2003,它引入了过程指针,所以我认为这只是一个疏忽,但我看到了