Порядок логических операций (потенциальная ошибка 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
могут быть ссылки, когда нет.