2016-05-09 9 views
1

目的は、任意のタイプのランク1の割り当てを処理できる単一の割り当てルーチンを作成することです。私たちのコードライブラリは、標準化されたエラートラップを持つ単一の呼び出しを持つことができます。Fortranの多態配列割り当てルーチン

コンパイラエラーは、次のとおりです。

generic_allocation.f08:32:27: 

     call myAllocator (array_int, source_int, lambda) 
          1 
Error: Actual argument to ‘myarray’ at (1) must be polymorphic 
generic_allocation.f08:33:27: 

     call myAllocator (array_real, source_real, lambda) 
          1 
Error: Actual argument to ‘myarray’ at (1) must be polymorphic 

はこのコードが修正することはできますか?

module mAllocator 
    implicit none 
contains 
    subroutine myAllocator (myArray, source_type, lambda) 
     class (*), allocatable, intent (inout) :: myArray (:) 
     class (*),    intent (in) :: source_type 
     integer,     intent (in) :: lambda 

     integer     :: alloc_status = 0 
     character (len = 512) :: alloc_message = '' 
      allocate (myArray (1 : lambda), source = source_type, stat = alloc_status, errmsg = alloc_message) 
      if (alloc_status /= 0) then 
       write (*, "(' allocation errmsg = ', g0, '.')") trim (alloc_message) 
       stop 'Fatal error in subroutine myAllocator' 
      end if 
    end subroutine myAllocator 
end module mAllocator 

program generic_allocation 

    use mAllocator, only : myAllocator 

    implicit none 

    integer, parameter :: lambda = 10 
    integer, parameter :: source_int = 1 
    real, parameter :: source_real = 1.0 

    integer, allocatable :: array_int (:) 
    real, allocatable :: array_real (:) 
     call myAllocator (array_int, source_int, lambda) 
     call myAllocator (array_real, source_real, lambda) 
end program generic_allocation 

FORTRAN: polymorphism allocationに示すように、コードの最初のバージョンはselect type構築物に依存:

テストコードは、整数のアレイと、次に実際の配列を割り当てよう。使用される別の参考文献はFortran polymorphism, functions and allocationです。

のgfortranバージョンは6.0

$ gfortran -v 
Using built-in specs. 
COLLECT_GCC=gfortran 
COLLECT_LTO_WRAPPER=/opt/gnu/6.0/libexec/gcc/x86_64-pc-linux-gnu/6.0.0/lto-wrapper 
Target: x86_64-pc-linux-gnu 
Configured with: ./configure --prefix=/opt/gnu/6.0 --enable-languages=c,c++,fortran,lto --disable-multilib --disable-werror 
Thread model: posix 
gcc version 6.0.0 20160227 (experimental) (GCC) 
+2

*目標は、任意のタイプのランク1の割り当てを処理できる単一の割り当てルーチンを作成することです。* allocateが提供するものではありませんか? –

答えて

4

であるあなたは、実際の宣言された型と一致していないいくつかのタイプにオブジェクトを割り当てるから手続きを防ぐために、場所に置く、言語の意図的な制約に直面しています引数。あなたのアロケータがarray_intに対応する仮引き数をREAL型に割り当てていたらどうなるか考えてみてください。

単一のプロシージャで目標を達成することはできませんが、1つのソースコードを作成してから、複数のプロシージャの本体にインクルードし、各宣言されたタイプ(および種類)あなたが対処したいと思っている。

! In AllocateBody.i90 
integer, intent(in) :: lambda 
integer     :: alloc_status 
character (len = 512) :: alloc_message 
allocate (myArray (1 : lambda), & 
    source = source_type, & 
    stat = alloc_status, & 
    errmsg = alloc_message) 
if (alloc_status /= 0) then 
    write (*, "(' allocation errmsg = ', g0, '.')") & 
     trim (alloc_message) 
    stop 'Fatal error in subroutine myAllocator' 
end if  


! Elsewhere. 
subroutine my_allocator_integer(myArray, source_type, lambda) 
    integer, intent(out), allocatable :: myArray(:) 
    integer, intent(in) :: source_type 
    include 'AllocateBody.i90' 
end subroutine my_allocator_integer 

subroutine my_allocator_real(myArray, source_type, lambda) 
    real, intent(out), allocatable :: myArray(:) 
    real, intent(in) :: source_type 
    include 'AllocateBody.i90' 
end subroutine my_allocator_real 

subroutine my_allocator_foo(myArray, source_type, lambda) 
    type(foo), intent(out), allocatable :: myArray(:) 
    type(foo), intent(in) :: source_type 
    include 'AllocateBody.i90' 
end subroutine my_allocator_foo 

これらのすべての手順を1つの総称名の後ろに置くことができます。

しかし、あなたがこれに着手する前に、現代のFortranでは、割り当て可能なものがALLOCATEステートメントなしでも割り当てられることに注意してください - 割り当て可能な変数への単純な割り当てはALLOCATEDになる可能性があります。これらの場合のエラーメッセージを処理する方法はありません。また、非常に多くのコーディング構造が存在し、コンパイラは内部的なニーズに合わせてメモリを割り当てます。これはエラーを処理する方法がありません。より低いレベルでは、オペレーティングシステムが実際にプログラムのメモリ要求を実行する方法もあなたのために働いています。システムがオーバーコミットされている可能性があります。また、割り当て後も十分なメモリエラーがオペレーティングシステムによってプロセスに報告されませんステートメントが完了しました。組み合わせて、使用可能なメモリが非常に少なく、小さなオブジェクトの割り当てに失敗した場合、エラー報告コードを実行するためにコンパイラが使用できるメモリが不足している可能性があります。また、コンパイラの実行時に、単純な整数コードと文字メッセージを使用して通信できるプログラムの状態や障害の理由がわかりやすいという問題もあります。たとえば、コンパイラのランタイムによってユーザーにスタックトレースを与えることができますそれ以外の場合にはプログラムに戻すことができるメッセージに加えて、同様のものであってもよい。

プログラマーが提供した小さな割り当てでは、エラー報告が非常に生産的ではない可能性があります。

特定の障害の確率が高く、その理由がうまく伝達され、実行される可能性が高い場合(「あなたの問題の次元が大きすぎます!もう一度やり直してください... ")。

関連する問題