c_loc () с динамическими массивами - PullRequest
2 голосов
/ 21 февраля 2012

Я новичок в Фортране и пытаюсь принять код ifort для компиляции с gfortran.

У меня проблема с функцией c_loc(), которая в ifort, кажется, принимает динамические массивы, но с компиляцией gfortran останавливается с ошибкой:

Ошибка: аргумент 'septr1' к 'c_loc' в (1) должен быть связанным скалярным указателем

Так кто-нибудь знает, как адаптировать следующий код ifort для компиляции с gfortran?

integer(c_int), dimension(:), pointer  :: septr1=>null()
type(c_PTR) :: septr

allocate (septr1(10))
septr1 = 33
septr = c_loc(septr1)

Ответы [ 2 ]

2 голосов
/ 21 февраля 2012

Похоже, что это требование старого Фортрана 2003 и ослабленного в Фортране 2008. Более поздний gfortran (5+) принимает это.


Вы можете получить местоположение начала массивазначение со смещением 0 в C.

septr = c_loc(septr1(1))

или вообще не 1, а lbound (septr1).

См. Требования к аргументу c_loc в Metcalf, Reid и Cohen или в стандарте Fortran.


Как правило, гораздо лучше передавать массив по ссылке обычным способом Fortran, а непостроить явный указатель c.Например:

 call some_c_function(n,A)

где функция some_c_ имеет интерфейс Fortran

 interface
  subroutine some_c_function(n,A) bind(C)
   use iso_c_binding,only: c_int,c_float    !you can use also import here

   integer(c_int),value      :: n
   real(c_float),dimension(n):: A
  end subroutine some_c_function
 end interface

для прототипа C

 void some_c_function(int n, float* A)  //(hope so, I am not so good in C).
0 голосов
/ 17 мая 2013

Разработчики ifort говорят, что проверка соответствия c_loc стандартам, включая его более ограниченное использование, чем унаследованный LOC (), не требуется положениями стандарта Fortran.Возможно, ввиду более широкой сферы полезного применения этой встроенной функции в современных стандартах и ​​необходимости ограничивать область применения, которую необходимо протестировать, большинство компиляторов отклонят нестандартное использование.

...