3

コード

program asd

real,pointer        :: a,b,c

allocate(a)
a=2.0
b=>a
c=>a
deallocate(b) !
print *, associated(c,target=a) ! T

end program

Intel コンパイラで T を返します。「b」は「a」の完全なエイリアスではないと結論付けます。これは、「b」を使用して「a」の割り当てを解除できないためです。だから私の質問は次のとおりです。

function ptr
  real,pointer   :: var,ptr
  allocate(var)
  ptr=>var
end function

この関数を呼び出した後で var の割り当てを解除することは可能ですか?

どうもありがとうございます-

4

1 に答える 1

7

規格によると(セクション6.3.3.2):

...ポインターターゲットの割り当てを解除すると、ターゲットまたはターゲットの一部に関連付けられている他のポインターのポインター関連付けステータスが未定義になります。

さらに、セクション16.4.2.1には、次のように書かれています。

ポインターは、関連付け済み、関連付け解除済み、または未定義のポインター関連付けステータスを持つ場合があります。

注16.3では、次のことを指摘しています。

モジュールプログラムユニットからのポインタは、使用の関連付けを介してサブプログラムでアクセスできます。そのようなポインタは、そのようなターゲットが保存されない限り、サブプログラムで宣言されたターゲットよりも長い存続期間を持ちます。したがって、そのようなポインタがローカルターゲットに関連付けられている場合、サブプログラムによって定義されたプロシージャが実行を完了すると、ターゲットが存在しなくなり、ポインタが「ぶら下がっている」ままになる可能性があります。この標準は、そのようなポインタが未定義の関連付けステータスを持っていると見なします。それらは関連付けられておらず、関連付けも解除されていません。それらのステータスが再確立されるまで、それらはプログラムで再び使用されてはなりません。ポインタターゲットが存在しなくなったことを検出できるようにするためのプロセッサの要件はありません。

つまり、取得するIntelからの結果は、未定義の関連付けステータスがあり、コンパイラーが任意の方法でレポートできる.TRUE.ため、コンパイラー固有であるということです。を介しcてアクセスしようとすると、メモリエラーが発生します(または、機能したとしても、定義されておらず、保証されていません)。ac

同様に、サンプル関数も同様に危険です。これはvar、関数が戻ったときに存在する保証がないためです。つまり、ptr関数の結果は再び未定義になります。varしたがって、の結果を介してアクセスしようとするとptr、メモリエラーが発生します。

関数を機能させたい場合は、次のようにする必要があります。

function ptr
  real, pointer, save :: var
  real,pointer   :: ptr
  allocate(var)
  ptr=>var
end function

もちろん、これは究極の疑問を投げかけます-なぜALLOCATEポインタなのか?ALLOCATABLEターゲットに使用してTARGET属性を指定する方がはるかに安全です。

于 2012-10-16T04:30:53.407 に答える