Порядок логических операций (потенциальная ошибка ifort)

Прежде чем сообщить об этом как об ошибке компилятора на форумах Intel, я хотел бы знать, соответствует ли следующее стандартному. Мой вопрос: всегда ли порядок логических операций фиксирован в Фортране?

! main.f90
  interface
     subroutine f(x)
       logical, intent(in), optional :: x
     end subroutine f
  end interface
  call f(.false.)
  call f(.true.)
  call f()
end program

! f.f90
subroutine f(x)
  logical, intent(in), optional :: x
  print*, present(x) .and. x
end subroutine f

gfortran main.f90 f.f90 && ./a.out печать

F
T
F

ifort main.f90 f.f90 && ./a.out печать

 F
 T
forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image              PC                Routine            Line        Source             
a.out              0000000000476D75  Unknown               Unknown  Unknown
a.out              0000000000474997  Unknown               Unknown  Unknown
a.out              0000000000444264  Unknown               Unknown  Unknown
a.out              0000000000444076  Unknown               Unknown  Unknown
a.out              0000000000425176  Unknown               Unknown  Unknown
a.out              00000000004027A0  Unknown               Unknown  Unknown
libpthread.so.0    00007F3560702E80  Unknown               Unknown  Unknown
a.out              0000000000402633  Unknown               Unknown  Unknown
a.out              000000000040260F  Unknown               Unknown  Unknown
a.out              00000000004025AE  Unknown               Unknown  Unknown
libc.so.6          00007F3560371710  Unknown               Unknown  Unknown
a.out              00000000004024A9  Unknown               Unknown  Unknown

Я использую GCC 5.3.0 и Ifort 16.0.2.

1 ответ

Решение

Нет, стандарты Fortran не дают никаких гарантий относительно порядка, в котором оцениваются логические выражения. Как и математические выражения, компиляторы могут свободно переупорядочивать их в порядки, которые были бы эквивалентны в идеальном мире "реальной логики" (или "настоящей математики"), но которые не эквивалентны в несовершенном мире компьютеров.

Вы можете установить порядок оценки следующим образом:

if (.not. present(x)) then
    print*, .false. 
else
    print*, x
end if

Моя копия проекта стандарта включает в себя пункт

7.1.5.4.2 Оценка логических внутренних операций

Как только интерпретация логической внутренней операции установлена, процессор может оценить любое другое выражение, которое является логически эквивалентным, при условии, что целостность скобок в любом выражении не нарушена.

Моя интерпретация стандарта заключается в том, что программа не соответствует, поскольку ссылается на необязательный аргумент, которого нет. Обратитесь к разделу 12.5.2.12 3 (1), который запрещает это. Потому что порядок оценки операндов .and. оператор не определен x могут быть ссылки, когда нет.

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