Общие процедуры с привязкой к типу с аргументами процедуры

Я пытаюсь написать общую процедуру с привязкой к типу, которая принимает в качестве параметров различные функции обратного вызова. При компиляции следующего кода (с ifort 12.1.3) я получаю следующее предупреждение:

module test

type :: a_type
  contains
  procedure :: t_s => at_s
  procedure :: t_d => at_d
  generic :: t => t_s,t_d
end type a_type

abstract interface
  integer function cb_s(arg)
  real(4) :: arg
  end function cb_s

  integer function cb_d(arg)
  real(8) :: arg
  end function cb_d
end interface

contains

subroutine at_s(this,cb)
  class(a_type) :: this
  procedure(cb_s) :: cb 
end subroutine

subroutine at_d(this,cb)
  class(a_type) :: this
  procedure(cb_d) :: cb 
end subroutine

end module test

Предупреждение:

compileme.f(27): warning #8449: The type/rank/keyword signature for this specific
procedure matches another specific procedure that shares the same generic
binding name.   [AT_D]

Похоже, что компилятор не различает разные интерфейсы функций при использовании в качестве аргументов процедуры...

Мой вопрос: почему эти типы не проверяются и каков правильный и чистый способ написания общих процедур с привязкой к типу с процедурами или указателями процедур в качестве аргументов?

Возможное решение

Как отметил Владимир Ф., проверяются только возвращаемые аргументы функции обратного вызова. В моем случае можно просто немного изменить интерфейсы функций:

abstract interface
  real(4) function cb_s(arg)
  real(4) :: arg
  end function cb_s

  real(8) function cb_d(arg)
  real(8) :: arg
  end function cb_d
end interface

person Omar Awile    schedule 08.07.2012    source источник


Ответы (1)


Компилятор прав, потому что 12.4.3.4.5 Ограничения на обобщенные объявления в Fortran 2008

Два фиктивных аргумента различимы, если - один является процедурой, а другой - объектом данных, - они оба являются объектами данных или известно, что они являются функциями, и ни один из TKR не совместим с другим, - один имеет атрибут ALLOCATABLE, а другой имеет атрибут POINTER, или - одна является функцией с ненулевым рангом, а другая, как известно, не является функцией.

Это означает, что обе ваши функции являются целочисленными функциями, поэтому их нельзя различить.

person Vladimir F    schedule 08.07.2012
comment
Да, вы, конечно, правы, я ошибся при написании заголовка, очевидно, это не указатели на процедуры. И да, обе они являются целочисленными функциями, но их аргументы — один раз real(4) и один раз real(8). Я думал, разные настоящие виды различимы? Кроме того, как бы вы поддерживали фиктивные аргументы функции одинарной и двойной точности в одной процедуре привязки универсального типа? - person Omar Awile; 09.07.2012
comment
Хорошо, я попробовал еще две вещи, чтобы лучше понять это: (1) я заменил целочисленные возвращаемые значения cb_s и cb_d на real(4) и real(8) соответственно, и хотя это меняет семантику, это работает. Значит, Fortran проверяет только возвращаемое значение функций-фиктивных аргументов? (2) Я заменил функции подпрограммами, принимающими дополнительный параметр для возвращаемого значения, и объявил намерение аргументов - это снова не удалось с тем же предупреждением, что и раньше... - person Omar Awile; 09.07.2012
comment
Да, проверяются только возвращаемые значения. Вы также можете отличить функции от подпрограмм. Если бы фиктивные аргументы можно было отличить по их фиктивным аргументам, это могло бы привести к длинной, возможно, бесконечной цепочке, возможно, через множество модулей. - person Vladimir F; 09.07.2012
comment
Хорошо спасибо! Тогда я думаю, что нет решения, кроме взлома, который я предложил в комментарии выше. - person Omar Awile; 09.07.2012