Как передать указатель Cray в подпрограмму?

#fortran #fortran77 #cray-pointers

#fortran #fortran77 #указатели Cray

Вопрос:

Я передаю указатель Cray, который сопоставляется с переменной, в подпрограмму Fortran. Это описано ниже:

 program test
  integer val
  pointer (ptr_val, val)

  print *, "1:", loc(val)
  print *, "1:", ptr_val

  CALL DPMALLOC(ptr_val, sizeof(val))

  print *, "2:", loc(val)
  print *, "2:", ptr_val

  val = 999
  call foo(val)

end program test

subroutine foo(val)
  integer val
  print *, "3:",val
  print *, "3:", loc(val)
  print *, "3:", ptr_val
  call DPMALLOC(ptr_val, sizeof(val))
  print *, "4:", ptr_val
  print *, "4:", loc(val)
  return
end subroutine foo
  
 void dpmalloc_(void **data, int *size){ 
    *data =(void *) malloc(*size);
    printf("mallocn");
}
  

Вывод:

  1:                   0
 1                    0
 2:             30743328
 2:             30743328
 3:         999
 3:             30743328
 3:  7.82827652E-38
 4:  7.82833033E-38
 4:             30743328
  

Поэтому, похоже, я не могу использовать глобальный указатель в подпрограмме. Как я могу это исправить?

Комментарии:

1. На самом деле вы не используете Fortran 77. Указатели Cray никогда не были частью этого или любого другого международного стандарта и, следовательно, по своей сути непереносимы. Как такового четко определенного способа сделать это не существует; вам придется прочитать документацию вашего компилятора.

2. Может быть важно, какой компилятор вы используете. И иногда имеет смысл немного ошибиться и перейти к fortran90 … например, заменить c_malloc на ALLOCATE и т. Д. software.intel.com/en-us/forums /…

3. Чтобы ответить на ваш вопрос, вы должны рассказать нам больше. Мне не хватает кода или, по крайней мере, заголовков подпрограмм. И мне также не хватает описания вашей реальной проблемы. В чем ваш вопрос? Есть ли сообщение об ошибке arny? Как это выглядит? Или неправильный результат? Сбой?

4. Но обратите внимание, что использование обоих val и ptr_val звучит для меня очень подозрительно. Если вы измените ptr_val , я ожидаю сбоя или подобной катастрофы.

5. Если вы добавите implicit none в подпрограмму (и основную программу), вы заметите, что у вас нет «глобального указателя».

Ответ №1:

Как указывает francescalus, вы действительно должны всегда использовать IMPLICIT NONE . Это очень, очень важно. Если вам нужно, не нужно заботиться о строгой совместимости с FORTRAN77, потому что указатели Cray в любом случае являются расширением. Так что используйте IMPLICIT NONE !

Это скажет вам, что ptr_val это было не определено в подпрограмме.

Вместо этого вы должны передать указатель, а не массив, и снова объявить ассоциацию указателей в подпрограмме:

 program test
  implicit none

  integer val
  pointer (ptr_val, val)

  print *, "1:", loc(val)
  print *, "1:", ptr_val

  CALL DPMALLOC(ptr_val, sizeof(val))



  print *, "2:", loc(val)
  print *, "2:", ptr_val

  val = 999
  call foo(ptr_val)

end program test

subroutine foo(ptr_val)
  implicit none

  integer val
  pointer (ptr_val, val)

  print *, "3:",val
  print *, "3:", loc(val)
  print *, "3:", ptr_val
  call DPMALLOC(ptr_val, sizeof(val))
  print *, "4:", ptr_val
  print *, "4:", loc(val)
  return
end subroutine foo
  

вывод:

 > ./a.out 
 1:                    0
 1:                    0
malloc
 2:             10391632
 2:             10391632
 3:         999
 3:             10391632
 3:             10391632
malloc
 4:             10391392
 4:             10391392