Запутанный отчет о проверке типов от 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 поддерживает разные схемы нумерации видов (
Как обычно, если вы считаете, что сообщение об ошибке компилятора можно улучшить, обратитесь с предложением к поставщику компилятора. Если разработчики согласятся и сочтут это целесообразным, возможно, вместе с десятками других запросов, сообщение об ошибке и диагностика могут быть изменены на те, которые вы предпочитаете.