Почему ifort -warn выдает все ошибки при несоответствии интерфейса?

Вот пример кода:

! Author: Svetlana Tkachenko [email protected]
! License: GPLv3 or later

subroutine myprint(var) 
!    integer :: var 
!    print *, 'Hi, my ', var 
end subroutine 

module testing 
   type triangle 
      integer :: point(3) 
   end type 
end module 

program main 
   use testing 
   type(triangle) :: mytriangle 
   mytriangle%point(1)=5 
   call myprint(mytriangle%point(1)) 
end program

он отлично работает с ifort -c file.f90, но ifort -warn all -c file.f90 приводит к ошибке:

blah.f90(4): warning #6717: This name has not been given an explicit type.   [VAR]
subroutine myprint(var) 
-------------------^
blah.f90(4): remark #7712: This variable has not been used.   [VAR]
subroutine myprint(var) 
-------------------^
blah.f90(19): error #6633: The type of the actual argument differs from the type of the dummy argument.   [POINT]
   call myprint(mytriangle%point(1)) 
---------------------------^
compilation aborted for blah.f90 (code 1)

Почему -warn all выдает ошибку? В справочной странице конкретно указано, что all не включает ошибки.

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


person naught101    schedule 02.03.2016    source источник
comment
Вы можете (должны) спросить продавца на официальном форуме поддержки о причинах их специфического поведения.   -  person Vladimir F    schedule 02.03.2016
comment
Я просто предполагаю, что вы знаете, что var неявно real в подпрограмме...   -  person Vladimir F    schedule 02.03.2016


Ответы (1)


Опция -warn all включает опцию -warn interfaces, инициирующую проверку интерфейса на наличие внешних процедур, в которых такие интерфейсы могут быть определены. Это часто для интерфейсов, созданных из внешних процедур в отдельных файлах, скомпилированных с опцией -gen-interfaces.

Именно эта опция -warn interfaces отвечает за сообщение об ошибке. Это позволяет проверить интерфейс внешней подпрограммы, потому что эта подпрограмма находится в том же файле, что и программа, которая на нее ссылается. Тогда у вас есть два варианта:

  • иметь внешнюю подпрограмму в отдельном файле, не скомпилированном с помощью -gen-interfaces;
  • не используйте -warn interfaces.

Для этого последнего вы можете использовать

ifort -warn all -warn nointerfaces ...

иметь все остальные предупреждения, кроме проверки интерфейса.

Однако для каждого из них предпочтительнее иметь соответствующий интерфейс. Следует отметить, что

subroutine myprint(var) 
!    integer :: var
end subroutine 

а также

subroutine myprint(var) 
     integer :: var
end subroutine 

две очень разные вещи при наличии правил неявной типизации по умолчанию. Они могут иметь одинаковый конечный эффект без исполняемых операторов (и т. д.), но характеристики совершенно разные.

person francescalus    schedule 02.03.2016
comment
Спасибо за объяснение. Все еще кажется ошибкой то, что об этом сообщается как об ошибке, а не как предупреждение, верно? - person naught101; 03.03.2016
comment
Я бы не назвал это ошибкой компилятора. Вы вызываете процедуру с неявным интерфейсом и просите компилятор проверить (с подразумеваемой опцией -warn interfaces), совпадают ли интерфейсы. Он делает это в некотором смысле (как я понимаю), притворяясь, что интерфейс был явным (см. документацию, в том числе по опции -gen-interfaces, и посмотрите на сгенерированный файл модуля: он действует так, как будто задействован модуль), что действительно делает это ошибка, а не предупреждение. Да, я вижу, что было бы неплохо иметь это в качестве предупреждения ... продолжение - person francescalus; 03.03.2016
comment
... и много раз, когда различные вызовы становятся намного проще, когда взламывание интерфейсов может быть выполнено определенным образом, но компилятор позволяет вам выбрать, сделать ли это ошибкой или нет: вы могли бы в фазе предупреждения повернуть это, а затем перекомпилировать без проверки интерфейса в качестве следующего шага. - person francescalus; 03.03.2016
comment
Подводя итог: ваш код является строго ошибочным, и компилятор проявляет любезность, выходя за рамки своих обычных обязанностей по обнаружению этого для вас. Но только потому, что ты попросил об этом. [Если я взгляну, например, на nagfor, нужно приложить усилия, чтобы разрешить прохождение того, что он считает плохими вызовами.] - person francescalus; 03.03.2016
comment
Да, достаточно справедливо, я думаю. Я надеялся, что смогу получить как можно больше предупреждений при успешной компиляции, чтобы я мог немного лучше отслеживать прогресс, но я думаю, что это не имеет большого значения. Параметр nointerfaces удаляет эту ошибку, но, возможно, я оставлю его включенным и просто постараюсь сначала решить эту конкретную проблему. Спасибо! - person naught101; 03.03.2016
comment
Как Владимир Ф прокомментировал ранее, форум Intel может быть лучшим местом для рассуждений или обоснований - я говорю только о своей интуиции. Ваш запрос, безусловно, кажется разумным, и, возможно, у экспертов есть альтернативное мнение. - person francescalus; 03.03.2016