Запутанный отчет о проверке типов от NAG Fortran

Рассмотрим следующий код Фортрана:

      program kinds_demo
  use iso_fortran_env, only: REAL64, INT32
  integer(int32), parameter :: n=10
  real(real64)    :: A(n, n)
  complex(real64) :: B(n, n)
  real(real64)    :: tr, u(n*n), v(n*n)

  a=1.0D0
  b=1.0D0
  
  call dcopy(n*n, a, 1, u, 1)
  call dcopy(n*n, b, 2, v, 1)
  
  tr=dot_product(u,v)

  print*,tr
  
end program kinds_demo

Я компилирую его с помощью новейшего компилятора NAG Fortran (NAG Fortran Compiler Release 7.1(Hanzomon), сборка 7114).

      nagfor -c -o kinds_demo.x kinds_demo.f90

и получить это сообщение об ошибке

Ошибка: kinds_demo.f90, строка 12: несогласованный тип данных COMPLEX(KIND(0d0)) (ранее DOUBLE PRECISION) для аргумента 2 в отношении DCOPY

Это ожидаемая ошибка , которая становится очевидной только при сравнении двухdcopyзвонки. После комментирования строки 11 (первый вызов) программа становится корректной. Заметьте, я не даю здесь ссылку. Поэтому сам тип аргументов здесь не имеет значения, важна лишь их последовательность. Но я не понимаю сообщение об ошибке. Разве это не должно быть написано как

Ошибка: kinds_demo.f90, строка 12: несогласованный тип данных COMPLEX(2)(ранее REAL(2)) для аргумента 2 в отношении DCOPY.

Заметить, чтоREAL64=2для компилятора NAG.

Здесь неоднократно подчеркивается , чтоdouble precisionне являетсяREAL64, но почему-то компилятор NAG (который известен дополнительными возможностями проверки ошибок и инструментами) предполагает прямо противоположное?

1 ответ

Типовые параметры — числа. Учитывать:

      use, intrinsic :: iso_fortran_env, only : real32  ! Value 1
use, intrinsic :: iso_c_binding, only : c_float   ! Value 1

implicit none

real(kind=1) a
real(kind=5**0) b
real(kind=SELECTED_REAL_KIND(radix=6)) c          ! Kind value 1
real(kind=real32) d
real(kind=c_float) e
real f                                            ! Default real has kind 1

end

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

Когда компилятор видит константное выражение, в котором требуется параметр вида, он оценивает выражение и использует его значение. Хотя компилятор может сохранить фактическое имя/выражение константы, используемое при объявлении объекта, для улучшения последующих отчетов об ошибках, это не является распространенным явлением.

Многие компиляторы будут жаловаться, но не с объяснением, как выбрал NAG, а просто с числовым значением:

      Error: Type mismatch between actual argument at (1) and actual argument at (2) (COMPLEX(8)/REAL(8)).

Компилятор NAG решает взять значение и выразить его более описательным образом с помощью сопоставления (используя схему нумерации по умолчанию 1,2,3):

  • значение вида 1 -> «реальный» / «сложный»
  • значение вида 2 -> «двойная точность» / «комплекс (вид (0d0)»
  • значение вида 3 -> «real(real128)» / «complex(real128)»

(для «нечетного» типа 2 обратите внимание, что «двойной комплекс» — это нестандартное расширение, предлагаемое компиляторами, отличными от NAG, и «комплекс (двойная точность)» не будет работать)

Ранее мы подчеркивали, что «двойная точность» не является «реальной (128)». Под этим мы не имеем в виду, но эти два значения не обязательно совпадают. Они могут быть одинаковыми.

Сопоставление призвано быть более полезным, чем простое число, а не идеально выражать код, который был замечен (на другом этапе компиляции). Обычно это все, что требуется. Напомним, что NAG поддерживает разные схемы нумерации видов (,и): использование числовых значений может вызвать путаницу.

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

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