- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi all,
I have written a module which I want to add a new subroutine without disturbing the previous one, so I want to wrap them with an interface, say:
[cpp]subroutine file_io_output_1(label, file_name, folder_name, card_name, buf, nd, dims) character(*), intent(in) :: label character(*), intent(in) :: file_name character(*), intent(in) :: folder_name character(*), intent(in) :: card_name real, intent(in) :: buf(*) integer, intent(in) :: nd integer, intent(in) :: dims(*) subroutine file_io_output_2(label, file_name, card_name, buf, nd, dims) character(*), intent(in) :: label character(*), intent(in) :: file_name character(*), intent(in) :: card_name real, intent(in) :: buf(*) integer, intent(in) :: nd integer, intent(in) :: dims(*) interface file_io_output module procedure file_io_output_1 module procedure file_io_output_2 end interface file_io_output[/cpp]
When I compiled the program, it complained:
error #6285: There is no matching specific subroutine for this generic subroutine call. [FILE_IO_OUTPUT]
It is more strange that I have two program files calling "file_io_output" with the same pattern of arguments (file_io_output_1), the first one is successfully compiled, but the second one failed. What's wrong?
Thank you for help!
DONG Li
Link Copied
4 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Please show the call that fails and the declarations of all its arguments.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Steve Lionel (Intel)
Please show the call that fails and the declarations of all its arguments.
Hi Steve,
The calling that passed the compilation is:
[plain]call file_io_output(trim(label), output_file, module_name, & "parcel_"//trim(q_name(i)), q(:,i), 1, (/nq/)) character(20) :: label character(50) :: output_file character(50) :: module_name integer :: nq character(8) :: q_name(nq) real :: q(np,nq) ! np is another integer variable[/plain]
The calling that failed the compilation is:
[plain]call file_io_output("constant", output_file, folder_name, & "mesh_"//trim(x_name(i)), x(:,:,:,i), 3, num_grid) character(50) :: output_file character(50) :: folder_name ! identical to module_name previously character(8) :: x_name(nd) ! nd is an integer variable integer :: num_grid(3) real, allocatable :: x(:,:,:,:) ! The actual dimensions are num_grid(1) X num_grid(2) X num_grid(3) X nd [/plain]
Before I added "file_io_output_2", the compilation is ok. So what is the side effect of interface "file_io_output"?
Thank you for help!
DONG Li
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - DONG Li
Before I added "file_io_output_2", the compilation is ok. So what is the side effect of interface "file_io_output"?
I assume that before you added file_io_output_2, you weren't using using a generic interface.
When you invoke a specific name, an assumed size argument like buf can be associated with an actual argument of any rank. Thus, you could associate it with that 3-dimensional subsection of x, even though buf is declared 1-dimensional.
Once you were using a generic interface, rank is one of the attributes used to select the appropriate specific routine, so a 3-dimensional actual argument now requires a 3-dimensional dummy argument. Since your generic interface didn't have one of those, you got an error message. (In the example that worked with the generic interface, you were passing a 1-dimensional subsection of q, so ranks matched.)
If you wanted to make this work, you could add to the generic interface another routine (say "file_io_ouput_1_3d") with the same arguments as file_io_ouput_1 except that buf is buf(:,:,:) instead of buf(*). This routine could then directly call the specific file_io_output_1 to actually do the work. (Because this would be a direct call to the specific, instead of a call to the generic, the rank mismatch would again be allowed.)
-Kurt
If you create these additional "glue" routines with assumed-shape buf arguments to match various dimensionalities, you could create versions with no nd or dims arguments, as these can be recreated with an appropriate constant and shape(buf) respecitively.
I believe I read that Fortran 2008 will have a feature that would allow "assumed-rank" arrays, but since the Fortran 2008 draft has not yet been formally adopted, I expect is will be quite some time before such a feature would make its way into ifort.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - hirchert
I assume that before you added file_io_output_2, you weren't using using a generic interface.
When you invoke a specific name, an assumed size argument like buf can be associated with an actual argument of any rank. Thus, you could associate it with that 3-dimensional subsection of x, even though buf is declared 1-dimensional.
Once you were using a generic interface, rank is one of the attributes used to select the appropriate specific routine, so a 3-dimensional actual argument now requires a 3-dimensional dummy argument. Since your generic interface didn't have one of those, you got an error message. (In the example that worked with the generic interface, you were passing a 1-dimensional subsection of q, so ranks matched.)
If you wanted to make this work, you could add to the generic interface another routine (say "file_io_ouput_1_3d") with the same arguments as file_io_ouput_1 except that buf is buf(:,:,:) instead of buf(*). This routine could then directly call the specific file_io_output_1 to actually do the work. (Because this would be a direct call to the specific, instead of a call to the generic, the rank mismatch would again be allowed.)
-Kurt
If you create these additional "glue" routines with assumed-shape buf arguments to match various dimensionalities, you could create versions with no nd or dims arguments, as these can be recreated with an appropriate constant and shape(buf) respecitively.
I believe I read that Fortran 2008 will have a feature that would allow "assumed-rank" arrays, but since the Fortran 2008 draft has not yet been formally adopted, I expect is will be quite some time before such a feature would make its way into ifort.
Hi hirchert,
Thank you for your detail explanation!
DONG Li

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page