#arrays #fortran #language-lawyer #gfortran #intel-fortran
#массивы #fortran #язык-юрист #gfortran #intel-fortran
Вопрос:
Этот код компилируется в gfortran, Intel Fortran и Solaris Studio
real, dimension(:) :: A(2)
print *, size(A)
end
Результат равен 2.
Однако, когда в инструкции dimension выполняется попытка другой спецификации массива
dimension A(1)
real :: A(2)
print *, size(A)
end
все три компилятора выдают ошибку, что атрибут измерения был задан дважды.
Соответствует ли первый код стандарту и что именно стандарт (как можно более свежий) говорит об этой ситуации?
Ответ №1:
Стандарт гласит:
-
спецификация массива для объекта в инструкции объявления типа переопределяет любую спецификацию атрибута DIMENSION (…) в той же инструкции (F2018 8.2p2), при определении того, что инструкция указывает в качестве атрибута для объекта.
-
атрибут не может быть указан дважды (F2018 C815).
Первая программа соответствует поведению, наблюдаемому в соответствии со стандартом; вторая — нет, учитывая C815.
Эти правила применяются начиная с Fortran 90. Эквивалент C815 также находится в F77, F66 характерно неоднозначен…
Комментарии:
1. Синтаксис, используемый OP, кажется законным:
real,dimension(:) :: A(2)
. Но я удивлен, чтоreal,dimension(whatever,whatever,whatever...) :: A(2)
это вообще компилируется. Интересно, могли бы вы дать некоторое представление о том, когда и почему такое поведение может быть нормальным или полезным?2. @MattP По крайней мере, он жалуется, когда что-либо не объявлено и неявно не указано.
3. Однако,
real, dimension(1000.,1000.,1000.,1000.) :: A(2)
разрешено Intel и gfortran и отклонено Oracle. Я не знаю, что правильно.4. @VladimirF,
real, dimension(1000.,1000.,1000.,1000.) :: A(2)
это недопустимый оператор объявления Fortran. Границы массива в спецификации атрибута должны быть допустимыми выражениями спецификации, даже если они позже будут переопределены.5. @francescalus На самом деле, gfortran v. 6 и более поздние версии также отклоняют это.