Возможная ошибка на ifort

Поскольку я достаточно ленив для того, чтобы не открывать учетную запись в Intel, но не для комментирования stackexchange, я решил разместить это здесь. В любом случае, изучая фортран, я обнаружил, что пишу этот фрагмент кода F03:

module log_module
 implicit none
 public :: assignment(=), operator(+), operator(-), &
        operator(*), operator(==), operator(/=)
 private :: logical_to_integer, integer_to_logical, &
    log_plus_log, log_minus, log_times_log, &
    log_equals_log, log_nequals_log

 interface assignment(=)
    module procedure logical_to_integer, &
        integer_to_logical
 end interface

 interface operator(+)
     module procedure log_plus_log
 end interface

 interface operator(-)
     module procedure log_minus
 end interface

 interface operator(*)
     module procedure log_times_log
 end interface

 interface operator(==)
     module procedure log_equals_log
 end interface

 interface operator(/=)
     module procedure log_nequals_log
 end interface

contains
elemental function log_equals_log(x, y) result(log_result)
 logical, intent(in) :: x, y
 logical :: log_result

 log_result = x .eqv. y
end function log_equals_log

elemental function log_nequals_log(x, y) result(log_result)
 logical, intent(in) :: x, y
 logical :: log_result

 log_result = x .neqv. y
end function log_nequals_log

function log_plus_log(x, y) result(log_result)
 logical, intent(in) :: x, y
 logical :: log_result 

 log_result = x .or. y
end function log_plus_log

function log_minus(x) result(log_result)
 logical, intent(in) :: x
 logical :: log_result

 log_result = .not. x
end function log_minus

function log_times_log(x, y) result(log_result)
 logical, intent(in) :: x, y
 logical :: log_result

 log_result = x .and. y
end function log_times_log

subroutine logical_to_integer(i, log_exp)
 integer, intent(out) :: i
 logical, intent(in) :: log_exp

 if(log_exp) then
    i = 1
 else
    i = 0
 end if
end subroutine logical_to_integer

subroutine integer_to_logical(logic, inte)
 integer, intent(in) :: inte
 logical, intent(out) :: logic

 if(inte == 0) then
    logic = .false.
 else
    logic = .true.
 end if
end subroutine integer_to_logical
end module log_module

program test
 use log_module
 implicit none
 integer :: i, j
 logical :: k
 logical, dimension(:), allocatable :: a, b

 a = [.true., .true.]
 b = [.false., .true.]
 print *, a
 i = .false.
 print *, i
 j = (5 < 7) .and. (sin(0.3) < 1.0)
 print *, j

 k = 3*5 - 5*3

 if(.not.k) print *, "Conversion to logical is correct"

 print *
 print *, .false. + .true.
 print *, .true. * .true.
 print *, (2.2>5.5) + (2.2<5.5) ! + has higher precedence than < or >
 print *, 2.2>5.5 .or. 2.2<5.5  ! see my point?
 print *
 print *, [.true., .false.] == [.true., .false.]
 if(all(a == b)) then
    print *, "something's wrong"
 else if(any(a /= b)) then
    print *, "Array non-equality check"
 end if
end program test

Итак, я скомпилировал его с помощью ifort и получил сообщение "что-то не так", затем скомпилировал его с помощью gfortran, и он работает, как и ожидалось. Кажется, что-то не работает при попытке назначить логические массивы для переменной логического массива, которая может быть размещена (здесь a и b).

В настоящее время я использую пробную версию ifort 15. В будущем я планирую купить пакет студента (200 долларов за лицензию) для моих кодов численного моделирования. Кто-то может спросить: "Почему ты не продолжаешь пользоваться гфортраном?" ну, мне нравятся возможности Fortran 2003, и некоторые важные аспекты языка еще не реализованы в gfortran:(.

Комментарии? Предложения? Жалобы?

1 ответ

Решение

Ну это не ifort... Вы используете относительно известную особенность (я думаю, 2003), чтобы распределить левую сторону, назначив массив для размещения:

a = [.true., .true.]
b = [.false., .true.]

Для внутреннего присваивания это деактивируется по умолчанию для ifort, С помощью -assume realloc-lhs во время компиляции эту функцию можно активировать, и ваш код компилируется и запускается, как и ожидалось.

Другие вопросы по тегам