1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

最適化オプションによる結果の違いin Fortran

Posted at

コンパイルの最適化オプションによって結果に違いが出る場合があります。
Fortranにおいて、わかりにくいバグが発生したので、備忘録的にこちらに書いておきます。

突然ですが、以下のFortranコードを見てください。

test.f90
module testmodule
    type testtype
        contains 
        procedure::test
    end type testtype

    contains

    subroutine test(self,i,v)
        implicit none
        class(testtype)::self
        integer,intent(in)::i
        complex(8),intent(out)::v
    
        write(*,*) "1",v*i

    end subroutine
end module testmodule

program main
    use testmodule
    implicit none

    complex(8)::v
    integer::i
    type(testtype)::t1

    i = 10
    v = 1d0
    call t1%test(i,v)
    i = 10
    v = 1d0
    call test2(i,v)
    !write(*,*) v

    contains 


end program main

subroutine test2(i,v)
    implicit none
    integer,intent(in)::i
    complex(8),intent(out)::v

    write(*,*) "2",v*i
    
end subroutine

このコード、gfortranでのコンパイルの最適化レベルのオプションの違いによって、異なる結果を返します。

gfortran test.f90

だと、

 1               (10.000000000000000,0.0000000000000000)
 2               (10.000000000000000,0.0000000000000000)
gfortran test.f90 -O2

だと、

 1               (0.0000000000000000,0.0000000000000000)
 2               (10.000000000000000,0.0000000000000000)

となります。

実は、このコードは作成者としては10が出て欲しいコードです。
しかし、一箇所バグが混入しているため、最適化レベルによって結果が変わってしまっています。
バグはどこでしょうか?

答えは、

complex(8),intent(out)::v

complex(8),intent(in)::v

とすべきです。inとoutを間違って入力してしまった、ということです。
outなので本来は値が入力されないにも関わらず、直前でのvの値が入ってしまっていて、結果的にintent(inout)のような挙動をしています。オブジェクト指向で書いた場合にO2とした時は、それをちゃんと反映したのか、きちんとvの値が反映されず、10とは表示されません。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?