2017-06-09 15 views
1

私は以下の関数を書いて、6つの実数パラメータを取り、1D配列を返します。このエラーは、最終除き、上記テキストで5つのエラーの合計繰り返し実数配列をコンパイルするときの型エラー。 Fortranのエラー#7113

error #7113: Each ac-value expression in an array-constructor must have the same type and type parameters. [COS] 

FUNCTION G(a, b, c, d, e, f) 

    IMPLICIT NONE 

    ! SPECIFICATION SECTION 
    REAL,     INTENT(IN) :: a 
    REAL,     INTENT(IN) :: b 
    REAL,     INTENT(IN) :: c 

    REAL,     INTENT(IN) :: d 
    REAL,     INTENT(IN) :: e 
    REAL,     INTENT(IN) :: f 

    REAL, DIMENSION(1:3)    :: G 
    REAL, DIMENSION(3,3)    :: T  
    REAL, DIMENSION(1:3)    :: H 

    ! EXECUTION SECTION 
    T = RESHAPE((/1, 0, -sin(b), & 
        0, cos(a), sin(a)*cos(b), & 
        0, -sin(a), cos(a)*cos(b)/), & 
        (/3,3/)) 
    H = (/d, e, f/) 
    G = someOtherUnimportantFunction(H,T) 

    ! SUBPROGRAM SECTION 

END FUNCTION G 

この関数は、コンパイルとRESHAPE関数呼び出しと行にエラーが発生しません4には最後に[COS]がありません。このエラーは、1と0がtrig関数とは異なる型として解釈されていることを示唆しています。実際には、1を1.0に、0を0.0に変更すると関数が正しくコンパイルされます。しかし、私は同様のRESHAPEを持つ同様の多くの同様の関数を持っているので、角度の正弦と余弦に加えて1と0の両方の整数型式を呼び出すので、混乱します。それらのRESHAPE関数呼び出しはうまくコンパイルされます。なぜこのRESHAPE呼び出しが異なるのですか?

これまでのRESHAPEコマンドは、整数をREAL値の変数に暗黙的に型変換していました。なぜこのタイプの変換は起こっていないのですか?混合整数と実数型と正しくコンパイルRESHAPEコールの

例:

U = RESHAPE((/cos(j), 0, sin(j), 0, 1, 0, -sin(j), 0, cos(j)/),(/3, 3/)) 

UはREAL 3×3アレイ及びjは実数値の角度です。

+0

(...プログラマの意図ではないかもしれない)realが暗黙的であるため、このパターンは、「ダウンコンバート」integerに(場合によっては)問題かもしれないと思います[この質問](https://stackoverflow.com/q/30128290)は関連していますが、確かにより重複したターゲットがあります。 – francescalus

+0

私は戻って、以前のRESHAPEの呼び出しをより詳しく見ました。私が渡したすべての配列には、 '[0または1の整数値]'と '[trigFunction(angle)] 'という形式の複数の要素が含まれていました。しかし、問題のRESHAPE呼び出しだけが整数で始まります。残りは三角関数から始まりました。したがって、私はすべての型の配列を渡さなかった。最初の要素型は、残りの要素の型変換のために重要ですか? –

+0

コンストラクタ内のすべての要素は、 '[real :: ...]'構文が使われていない限り、同じ型と種類でなければなりません。 – francescalus

答えて

1

上記で見られるreshape(より正確には、reshape関数内に作成された一時配列)の動作は、特定のバージョンのコンパイラ(おそらくifort14?)のベンダー拡張です。下記のBCの結果を比較してください。使用するコンパイラとバージョンによって異なります。

! [compilers used] 
! ifort 14 and 16 (both with an option '-standard-semantics') 
! gfortran 4.8 and 7.1 
! Oracle studio fortran 12.5 
! PGI Fortran Community Edition 2017.4 

program main 
    implicit none 
    real :: A(3), B(3), C(3) 

    !------------------------- 
    ! RHS = uniform integer array 

    A = [ 1, 2, 3 ] !! an integer temporary array is created for RHS and assigned to A (with integer -> real conversion) 
    print *, [ 1, 2, 3 ] 
    print *, "A = ", A 

    ! gfortran: PASS 
    ! ifort16 : PASS 
    ! ifort14 : PASS 
    ! oracle : PASS 
    ! pgi  : PASS 

    !------------------------- 
    ! RHS = [ real, integer, integer ] 

    B = [ 1.1, 2, 3 ] 
    print *, [ 1.1, 2, 3 ] 
    print *, "B = ", B 

    ! gfortran: Error: Element in REAL(4) array constructor at (1) is INTEGER(4) 
    ! ifort16 : Error: If type specification is omitted, each element 
    !     in an array-constructor must have the same type 
    !     and kind type parameters. 
    ! ifort14 : PASS (*) 
    ! oracle : Error: All ac-value expressions in an array constructor 
    !     must have the same type and type parameters. 
    ! pgi  : PASS (*) 

    !------------------------- 
    ! RHS = [ integer, real, integer ] 

    C = [ 1, 2.2, 3 ] 
    print *, [ 1, 2.2, 3 ] 
    print *, "C = ", C 

    ! gfortran: Error: Element in INTEGER(4) array constructor at (1) is REAL(4) 
    ! ifort16 : Error: (same message as for B) 
    ! ifort14 : Error: Each ac-value expression in an array-constructor 
    !     must have the same type and type parameters. 
    ! oracle : Error: (same message as for B) 
    ! pgi  : PASS (**) 

    ! The error message from ifort-14 is the same as that shown in the question. 

end 

結果:

!------------------------- 
gfortran, ifort-16, oracle 

     1   2   3 
A = 1.000000 2.000000 3.000000 

! B and C => error 

!------------------------- 
ifort-14 

     1   2   3 
A = 1.000000 2.000000 3.000000 

     1.100000 2.000000 3.000000 (*) 
B = 1.100000 2.000000 3.000000 (*) 

! C => error 

!------------------------- 
PGI 
     1   2   3 
A = 1.000000 2.000000 3.000000  

     1.100000 2.000000 3.000000  
B = 1.100000 2.000000 3.000000  

     1   2   3   (**) 
C = 1.000000 2.000000 3.000000 (**) 

だから、配列コンストラクターに、異なるタイプの要素を混在しないようにおそらくより移植性がある(いくつかのコンパイラはそれを許可していても...)。

我々は[ real :: ... ]として配列コンストラクタの(均一な)要素のタイプを(コメントで示唆したように)を指定する一方、我々は、異なるタイプの要素を混在させることができるが、例えば:

B = [ real :: 1.1, 2, 3 ] 
print *, [ real :: 1.1, 2, 3 ] 
print *, "B = ", B 

C = [ real :: 1, 2.2, 3 ] 
print *, [ real :: 1, 2.2, 3 ] 
print *, "C = ", C 

れます(上記のすべてのコンパイラのために)提供します:

 1.100000 2.000000 3.000000 
B = 1.100000 2.000000 3.000000 

     1.000000 2.200000 3.000000 
C = 1.000000 2.200000 3.000000 

(*)integerrealに変換されるため、このパターンは単に許容し、少しの危害のようです。

(**)しかし、私は

+1

Fortranの標準的な振る舞いは、最初の要素から配列コンストラクタの一様な要素型を決定することだと思いますが、標準文書でどこに書かれているのか分かりません...(したがって、XDで確認してください) – roygvib

+0

そこに書き込む必要はありません。要素はすべて同じ型でなければなりません。最初の要素または最後の要素を最初に見ても問題ありません。 –

+1

あなたの情報をありがとう。要素の型が統一されていれば、最初の要素や最後の要素などの選択は型の決定には関係しないことは妥当と思われます。 (しかし、gfortranのエラーメッセージもやや誤解を招くようです...)答えから「最初の要素」を削除しました(そしてDocsページへのリンクを追加しました)。 – roygvib

関連する問題