Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Fortran > [General] Проверка типов на этапе компиляции


Автор: kamre 30.10.2006, 13:38
Есть ли в fortran проверка типов при компиляции? Т.е. говорится ли что-то об этом в стандарте? Или все зависит от компилятора и его настроек?
Вот пример кода:
Код

program ParamsTest
  implicit none
  integer :: a
  real :: b
  complex ::c
  a = 1
  b = 2.0
  call test(a, b, c)
  call test(a, a, c)
  call test(a, a, a)
  call test(a, b)
  call test(a)
end program ParamsTest

subroutine test(a, b, c)
  implicit none
  integer, intent(in) :: a
  real, intent(in) :: b
  complex, intent(out) ::c
  c = a + b
end subroutine test

Создал проект (с настройками по умолчанию) в VS2005 и компилирую с помощью IVFC9.1
Все успешно собирается, не выдает ни одной ошибки.
Но, разумеется, падает при запуске.
Почему такое странное поведение? 
Ведь вроде же не трудно понять, что из всех вызовов только два первые являются правильными.
Когда программировал на с++, таких приколов не было никогда:
Код

struct complex{
  double re, im;
};
void test(int a, double b, complex &c)
{
  c.re = a + b;
  c.im = 0.0;
}
void main() 
{
  int a = 1;
  double b = 2.0;
  complex c;
  test(a, b, c);
  test(a, a, c);
  test(a, a, a); // ERROR: cannot convert parameter 3 from 'int' to 'complex &'
  test(a, b);     // ERROR: function does not take 2 arguments
  test(a);         // ERROR: function does not take 1 arguments
}

Автор: kamre 31.10.2006, 09:27
Кстати, если подпрограмму сделать как внутреннюю:
Код

program ParamsTest
  implicit none
  integer :: a
  real :: b
  complex ::c
  a = 1
  b = 2.0
  call test(a, b, c)
  call test(a, a, c)
  call test(a, a, a)
  call test(a, b)
  call test(a)
contains
  subroutine test(a, b, c)
    implicit none
    integer, intent(in) :: a
    real, intent(in) :: b
    complex, intent(out) ::c
    c = a + b
  end subroutine test
end program ParamsTest

то компилятор показывает ошибки....
Правда ему и второй вызов не нравится, пишет о несоотвествии типов.
Еще можно вот так:
Код

program ParamsTest
  implicit none
  integer :: a
  real :: b
  complex ::c
  interface
    subroutine test(a, b, c)
      integer, intent(in) :: a
      real, intent(in) :: b
      complex, intent(out) ::c
    end subroutine
  end interface
  a = 1
  b = 2.0
  call test(a, b, c)
  call test(a, a, c)
  call test(a, a, a)
  call test(a, b)
  call test(a)
end program ParamsTest

subroutine test(a, b, c)
  implicit none
  integer, intent(in) :: a
  real, intent(in) :: b
  complex, intent(out) ::c
  c = a + b
end subroutine test


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

Автор: Cr@$h 17.1.2009, 09:31
Цитата(kamre @  30.10.2006,  14:38 Найти цитируемый пост)
Есть ли в fortran проверка типов при компиляции? Т.е. говорится ли что-то об этом в стандарте? Или все зависит от компилятора и его настроек?

Есть правила приведения типов. Эти правила и проверяются на этапе компиляции. При работе все данные интерпретируются тем самым верно. За исключением расширений типа объединений из С.

Цитата(kamre @  30.10.2006,  14:38 Найти цитируемый пост)
Создал проект (с настройками по умолчанию) в VS2005 и компилирую с помощью IVFC9.1
Все успешно собирается, не выдает ни одной ошибки.
Но, разумеется, падает при запуске.
Почему такое странное поведение? 
Ведь вроде же не трудно понять, что из всех вызовов только два первые являются правильными.

Такого не может быть.
Цитата(kamre @  31.10.2006,  10:27 Найти цитируемый пост)
Кстати, если подпрограмму сделать как внутреннюю:

У внутренней программы выден её интерфейс, поэтому компиляция возможна.
Цитата(kamre @  31.10.2006,  10:27 Найти цитируемый пост)
то компилятор показывает ошибки....
Правда ему и второй вызов не нравится, пишет о несоотвествии типов.

И правильно делает. Как и С++. Знаете почему? Эта перемена у вас помечена как возвращаемая из процедуры!
Цитата(kamre @  31.10.2006,  10:27 Найти цитируемый пост)
Еще можно вот так:

Указан интерфейс для внешней процедуры. Всё верно. Странно, если было бы иначе smile
Цитата(kamre @  31.10.2006,  10:27 Найти цитируемый пост)
Получается, что для всех не внутренних подпрограмм нужно определять интерфейс? 

Получается, что для любой подпрограммы должен быть интерфейс. Если она внутренняя -- он у неё есть автоматически. Если внешняя -- его нужно обязательно прописать. Так в большинстве языков программирования.
В первом случае вы просто поместили всё в один файл, а это ни о чём не говорит. Либо подпрограмма является внутренней для другой подпрограммы, либо является внутренней для головной программы, либо является внутренней для модуля. Другого не дано.
В принципе, можете попробовать описать подпрограмму перед головной программой как в С++.

Автор: kamre 17.1.2009, 14:33
Цитата(Cr@$h @ 17.1.2009,  09:31)
Цитата(kamre @  30.10.2006,  14:38 Найти цитируемый пост)
Есть ли в fortran проверка типов при компиляции? Т.е. говорится ли что-то об этом в стандарте? Или все зависит от компилятора и его настроек?

Есть правила приведения типов. Эти правила и проверяются на этапе компиляции. При работе все данные интерпретируются тем самым верно. За исключением расширений типа объединений из С.

Цитата(kamre @  30.10.2006,  14:38 Найти цитируемый пост)
Создал проект (с настройками по умолчанию) в VS2005 и компилирую с помощью IVFC9.1
Все успешно собирается, не выдает ни одной ошибки.
Но, разумеется, падает при запуске.
Почему такое странное поведение? 
Ведь вроде же не трудно понять, что из всех вызовов только два первые являются правильными.

Такого не может быть.
Цитата(kamre @  31.10.2006,  10:27 Найти цитируемый пост)
Кстати, если подпрограмму сделать как внутреннюю:

У внутренней программы выден её интерфейс, поэтому компиляция возможна.
Цитата(kamre @  31.10.2006,  10:27 Найти цитируемый пост)
то компилятор показывает ошибки....
Правда ему и второй вызов не нравится, пишет о несоотвествии типов.

И правильно делает. Как и С++. Знаете почему? Эта перемена у вас помечена как возвращаемая из процедуры!
Цитата(kamre @  31.10.2006,  10:27 Найти цитируемый пост)
Еще можно вот так:

Указан интерфейс для внешней процедуры. Всё верно. Странно, если было бы иначе smile
Цитата(kamre @  31.10.2006,  10:27 Найти цитируемый пост)
Получается, что для всех не внутренних подпрограмм нужно определять интерфейс? 

Получается, что для любой подпрограммы должен быть интерфейс. Если она внутренняя -- он у неё есть автоматически. Если внешняя -- его нужно обязательно прописать. Так в большинстве языков программирования.
В первом случае вы просто поместили всё в один файл, а это ни о чём не говорит. Либо подпрограмма является внутренней для другой подпрограммы, либо является внутренней для головной программы, либо является внутренней для модуля. Другого не дано.
В принципе, можете попробовать описать подпрограмму перед головной программой как в С++.

Уфф.. Я уже и забыл, что когда-то такое спрашивал на форуме, но уведомления по почте рулят smile

P.S. за это время я уже успел опять вернуться к "кодингу" на C++ (поменял работу), и даже стал засматриваться на Java... А расчетными задачами на фортране уже давно не занимался...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)