Возможная ошибка на 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
во время компиляции эту функцию можно активировать, и ваш код компилируется и запускается, как и ожидалось.