Bug 64138 - gfortran interface issue
Summary: gfortran interface issue
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.9.3
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-12-01 15:03 UTC by david
Modified: 2014-12-06 15:03 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2014-12-01 00:00:00


Attachments
a small code (395 bytes, text/plain)
2014-12-01 20:11 UTC, david
Details

Note You need to log in before you can comment on or make changes to this bug.
Description david 2014-12-01 15:03:03 UTC
Hi,

   I have created a complex number module:

       module complex_number_module
        implicit none

        integer, parameter :: loc_real_precision = 8

        type complex_number
          real(kind=loc_real_precision) :: real_part, imag_part
        end type complex_number

        interface c_sub
          module procedure c_sub_cc,    &      ! z1 - z2
                           c_sub_cr,    &      ! z1 - num, where num is a real number
                           c_sub_rc            ! num - z1, where num is a real number
        end interface

! --------------------------------------------------------------------------
        type (complex_number) function c_sub_cc (z1, z2)

        type (complex_number), intent(in) :: z1, z2

        c_sub_cc%real_part = z1%real_part - z2%real_part
        c_sub_cc%imag_part = z1%imag_part - z2%imag_part

        end function c_sub_ccj

! --------------------------------------------------------------------------
        type (complex_number) function c_sub_cr (z1, num)

        type (complex_number),     intent(in) :: z1
        real(kind=loc_real_precision), intent(in) :: num

        c_sub_cr%real_part = z1%real_part - num
        c_sub_cr%imag_part = z1%imag_part

        end function c_sub_cr

! --------------------------------------------------------------------------
        type (complex_number) function c_sub_rc (num, z1)

        type (complex_number),     intent(in) :: z1
        real(kind=loc_real_precision), intent(in) :: num

        c_sub_rc%real_part = num - z1%real_part
        c_sub_rc%imag_part = - z1%imag_part

        end function c_sub_rc

      end module complex_number_module

When I compile with gfortran (version 4.6.4), I got the following error:

module_twoway_rrtmg_aero_optical_util.F:14.85:

                 c_sub_rc            ! num - z1, where num is a real number
                                                                           1         
Error: Ambiguous interfaces 'c_sub_rc' and 'c_sub_cr' in generic interface 'c_sub' at (1)

I don't see any ambiguity and I don't encounter any problem with other compilers such pgi and ifort. Please advise.

Cheers,
David
Comment 1 kargls 2014-12-01 17:24:18 UTC
(In reply to david from comment #0)
> Hi,
> 
>    I have created a complex number module:
> 
>        module complex_number_module
>         implicit none
> 
>         integer, parameter :: loc_real_precision = 8
> 
>         type complex_number
>           real(kind=loc_real_precision) :: real_part, imag_part
>         end type complex_number
> 
>         interface c_sub
>           module procedure c_sub_cc,    &      ! z1 - z2
>                            c_sub_cr,    &      ! z1 - num, where num is a
> real number
>                            c_sub_rc            ! num - z1, where num is a
> real number
>         end interface
> 
> ! --------------------------------------------------------------------------
>         type (complex_number) function c_sub_cc (z1, z2)
> 
>         type (complex_number), intent(in) :: z1, z2
> 
>         c_sub_cc%real_part = z1%real_part - z2%real_part
>         c_sub_cc%imag_part = z1%imag_part - z2%imag_part
> 
>         end function c_sub_ccj
> 
> ! --------------------------------------------------------------------------
>         type (complex_number) function c_sub_cr (z1, num)
> 
>         type (complex_number),     intent(in) :: z1
>         real(kind=loc_real_precision), intent(in) :: num
> 
>         c_sub_cr%real_part = z1%real_part - num
>         c_sub_cr%imag_part = z1%imag_part
> 
>         end function c_sub_cr
> 
> ! --------------------------------------------------------------------------
>         type (complex_number) function c_sub_rc (num, z1)
> 
>         type (complex_number),     intent(in) :: z1
>         real(kind=loc_real_precision), intent(in) :: num
> 
>         c_sub_rc%real_part = num - z1%real_part
>         c_sub_rc%imag_part = - z1%imag_part
> 
>         end function c_sub_rc
> 
>       end module complex_number_module
> 
> When I compile with gfortran (version 4.6.4), I got the following error:
> 
> module_twoway_rrtmg_aero_optical_util.F:14.85:
> 
>                  c_sub_rc            ! num - z1, where num is a real number
>                                                                            1
> 
> Error: Ambiguous interfaces 'c_sub_rc' and 'c_sub_cr' in generic interface
> 'c_sub' at (1)
> 
> I don't see any ambiguity and I don't encounter any problem with other
> compilers such pgi and ifort. Please advise.
> 
> Cheers,
> David

Please attach the exact code you tried to compile.  The above is nonsense.
Comment 2 david 2014-12-01 20:11:44 UTC
Created attachment 34158 [details]
a small code
Comment 3 david 2014-12-01 20:13:45 UTC
(In reply to david from comment #0)
> Hi,
> 
>    I have created a complex number module:
> 
>        module complex_number_module
>         implicit none
> 
>         integer, parameter :: loc_real_precision = 8
> 
>         type complex_number
>           real(kind=loc_real_precision) :: real_part, imag_part
>         end type complex_number
> 
>         interface c_sub
>           module procedure c_sub_cc,    &      ! z1 - z2
>                            c_sub_cr,    &      ! z1 - num, where num is a
> real number
>                            c_sub_rc            ! num - z1, where num is a
> real number
>         end interface
> 
> ! --------------------------------------------------------------------------
>         type (complex_number) function c_sub_cc (z1, z2)
> 
>         type (complex_number), intent(in) :: z1, z2
> 
>         c_sub_cc%real_part = z1%real_part - z2%real_part
>         c_sub_cc%imag_part = z1%imag_part - z2%imag_part
> 
>         end function c_sub_ccj
> 
> ! --------------------------------------------------------------------------
>         type (complex_number) function c_sub_cr (z1, num)
> 
>         type (complex_number),     intent(in) :: z1
>         real(kind=loc_real_precision), intent(in) :: num
> 
>         c_sub_cr%real_part = z1%real_part - num
>         c_sub_cr%imag_part = z1%imag_part
> 
>         end function c_sub_cr
> 
> ! --------------------------------------------------------------------------
>         type (complex_number) function c_sub_rc (num, z1)
> 
>         type (complex_number),     intent(in) :: z1
>         real(kind=loc_real_precision), intent(in) :: num
> 
>         c_sub_rc%real_part = num - z1%real_part
>         c_sub_rc%imag_part = - z1%imag_part
> 
>         end function c_sub_rc
> 
>       end module complex_number_module
> 
> When I compile with gfortran (version 4.6.4), I got the following error:
> 
> module_twoway_rrtmg_aero_optical_util.F:14.85:
> 
>                  c_sub_rc            ! num - z1, where num is a real number
>                                                                            1
> 
> Error: Ambiguous interfaces 'c_sub_rc' and 'c_sub_cr' in generic interface
> 'c_sub' at (1)
> 
> I don't see any ambiguity and I don't encounter any problem with other
> compilers such pgi and ifort. Please advise.
> 
> Cheers,
> David

Hi,

   I have attached a smaller version of the code and the way I compiled the code is:

   gfortran -c -ffree-form d.F

Thanks,
David
Comment 4 kargls 2014-12-01 20:17:14 UTC
(In reply to kargl from comment #1)
> (In reply to david from comment #0)
> > Hi,
> > 
> >    I have created a complex number module:
> > 
> >        module complex_number_module
> >         implicit none
> > 
> >         integer, parameter :: loc_real_precision = 8
> > 
> >         type complex_number
> >           real(kind=loc_real_precision) :: real_part, imag_part
> >         end type complex_number
> > 
> >         interface c_sub
> >           module procedure c_sub_cc,    &      ! z1 - z2
> >                            c_sub_cr,    &      ! z1 - num, where num is a
> > real number
> >                            c_sub_rc            ! num - z1, where num is a
> > real number
> >         end interface
> > 
> > ! --------------------------------------------------------------------------
> >         type (complex_number) function c_sub_cc (z1, z2)
> > 
> >         type (complex_number), intent(in) :: z1, z2
> > 
> >         c_sub_cc%real_part = z1%real_part - z2%real_part
> >         c_sub_cc%imag_part = z1%imag_part - z2%imag_part
> > 
> >         end function c_sub_ccj
> > 
> > ! --------------------------------------------------------------------------
> >         type (complex_number) function c_sub_cr (z1, num)
> > 
> >         type (complex_number),     intent(in) :: z1
> >         real(kind=loc_real_precision), intent(in) :: num
> > 
> >         c_sub_cr%real_part = z1%real_part - num
> >         c_sub_cr%imag_part = z1%imag_part
> > 
> >         end function c_sub_cr
> > 
> > ! --------------------------------------------------------------------------
> >         type (complex_number) function c_sub_rc (num, z1)
> > 
> >         type (complex_number),     intent(in) :: z1
> >         real(kind=loc_real_precision), intent(in) :: num
> > 
> >         c_sub_rc%real_part = num - z1%real_part
> >         c_sub_rc%imag_part = - z1%imag_part
> > 
> >         end function c_sub_rc
> > 
> >       end module complex_number_module
> > 
> > When I compile with gfortran (version 4.6.4), I got the following error:
> > 
> > module_twoway_rrtmg_aero_optical_util.F:14.85:
> > 
> >                  c_sub_rc            ! num - z1, where num is a real number
> >                                                                            1
> > 
> > Error: Ambiguous interfaces 'c_sub_rc' and 'c_sub_cr' in generic interface
> > 'c_sub' at (1)
> > 
> > I don't see any ambiguity and I don't encounter any problem with other
> > compilers such pgi and ifort. Please advise.
> > 
> > Cheers,
> > David
> 
> Please attach the exact code you tried to compile.  The above is nonsense.

I fixed the above code.  I believe gfortran is correct to complain
about an ambiguous interface.  In the last two line below, which
of c_sub_rc and c_sub_cr should be called.

program foo
  use complex_number_module
  type(complex_number) a, b
  real(dp) x
  a%re = 1
  a%im = 2
  x = 1
  b = c_sub(a, x); print '(A,2F5.1)', 'a-x = ', b%re, b%im
  b = c_sub(x, a); print '(A,2F5.1)', 'x-a = ', b%re, b%im
  b = c_sub(z1=a, num=x); print '(A,2F5.1)', 'a-x = ', b%re, b%im
  b = c_sub(num=x,a); print '(A,2F5.1)', 'a-x = ', b%re, b%im
end program foo
Comment 5 david 2014-12-02 15:37:19 UTC
Hi,

   What is your fix?

   In the original code, c_sub_cr and c_sub_rc are distinct because the sequence of argument type are different. Other compilers have no problem to distinguish them. Please advise.

Cheers,
David
Comment 6 Steve Kargl 2014-12-02 16:05:24 UTC
On Tue, Dec 02, 2014 at 03:37:19PM +0000, wong.david-c at epa dot gov wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64138
> 
>    What is your fix?
> 

I meant I fixed the code you posted.  It was missing a CONTAINS
statement before c_sub_cc, and there is an extra 'j' on the
end of one of the 'end function c_sub_??' lines.

>    In the original code, c_sub_cr and c_sub_rc are distinct because the
> sequence of argument type are different. Other compilers have no problem to
> distinguish them. Please advise.

You can get the code to compile if you change the dummy
argument names in c_sub_cr and c_sub_rc to unique entities.
For example, (and yes I changed the function and variable
names while debugging)

      type(complex_number) function f2(z1, num)
         type (complex_number), intent(in) :: z1
         real(kind=dp), intent(in) :: num
         f2%re = z1%re - num
         f2%im = z1%im
       end function f2

      type(complex_number) function f3(num, z2)
         type (complex_number), intent(in) :: z2
         real(kind=dp), intent(in) :: num
         f3%re = num - z2%re
         f3%im = - z2%im
      end function f3

The only problem with this workaround is that you cannot
use keyword argument association.  For example,
   
   type(complex_number) :: z=complex_number(1.,2.)
   real x = 3. 
   z = c_sub(num=x, z)

The above is ambiguous because the reduced argument list for
f2 and f3 are identical, so the generic c_sub can be mapped
to either.  Fortunately, gfortran tries to help in this 
situation

% gfortran -o z -fmax-errors=1 a.f90
a.f90:53.18:

  b = c_sub(num=x, a);    print '(A,2F5.1)', '(x-a)? = ', b%re, b%im
                  1
Error: Missing keyword name in actual argument list at (1)
Fatal Error: Error count reached limit of 1.

Note, however, AFAIK, a keyword is not necessary and is not required.
IHMO, issuing this error message could in fact be considered a bug.
In fact, if you change the order of arguments to

  b = c_sub(a, num=x);    print '(A,2F5.1)', '(x-a)? = ', b%re, b%im

This will compile without error.  If the former line producing an
error about a missing keyword shouldn't the latter?
Comment 7 Dominique d'Humieres 2014-12-02 17:13:09 UTC
I was sure to have seen discussions about such issues: pr33997 and 

https://groups.google.com/forum/#!msg/comp.lang.fortran/GIcxE7GM1ek/aP7eJpQ-T7QJ

AFAIU the discussions, the relevant point for this PR is

> (b) A nonoptional non-passed-object dummy argument whose name
> is such that either the other procedure has no dummy argument
> with that name or the dummy argument with that name is distinguishable
> with it.

Along this line I have renamed num to num1 and z1 to z2 in c_sub_rc

       module complex_number_module
        implicit none

        integer, parameter :: loc_real_precision = 8

        type complex_number
          real(kind=loc_real_precision) :: real_part, imag_part
        end type complex_number

        interface c_sub
          module procedure c_sub_cc,    &      ! z1 - z2
                           c_sub_cr,    &      ! z1 - num, where num is a real number
                           c_sub_rc            ! num - z1, where num is a real number
        end interface

 contains
! --------------------------------------------------------------------------
        type (complex_number) function c_sub_cc (z1, z2)

        type (complex_number), intent(in) :: z1, z2

        c_sub_cc%real_part = z1%real_part - z2%real_part
        c_sub_cc%imag_part = z1%imag_part - z2%imag_part

        end function c_sub_cc

! --------------------------------------------------------------------------
        type (complex_number) function c_sub_cr (z1, num)

        type (complex_number),     intent(in) :: z1
        real(kind=loc_real_precision), intent(in) :: num

        c_sub_cr%real_part = z1%real_part - num
        c_sub_cr%imag_part = z1%imag_part

        end function c_sub_cr

! --------------------------------------------------------------------------
        type (complex_number) function c_sub_rc (num1, z2)

        type (complex_number),     intent(in) :: z2
        real(kind=loc_real_precision), intent(in) :: num1

        c_sub_rc%real_part = num1 - z2%real_part
        c_sub_rc%imag_part = - z2%imag_part

        end function c_sub_rc

      end module complex_number_module

program foo
  use complex_number_module
  type(complex_number) a, b
  real(loc_real_precision) x
  a%real_part = 1
  a%imag_part = 2
  x = 3
  b = c_sub(a, x); print '(A,2F5.1)', 'a-x = ', b%real_part, b%imag_part
  b = c_sub(x, a); print '(A,2F5.1)', 'x-a = ', b%real_part, b%imag_part
  b = c_sub(z1=a, num=x); print '(A,2F5.1)', 'a-x = ', b%real_part, b%imag_part
  b = c_sub(num=x,z1=a); print '(A,2F5.1)', 'a-x = ', b%real_part, b%imag_part
  b = c_sub(num1=x,z2=a); print '(A,2F5.1)', 'x-a = ', b%real_part, b%imag_part
end program foo

This made the code to compile and if I am not mistaken to produce the correct result

a-x =  -2.0  2.0
x-a =   2.0 -2.0
a-x =  -2.0  2.0
a-x =  -2.0  2.0
x-a =   2.0 -2.0


Out of curiosity why do want to handle complex numbers through types while they are perfectly handled in Fortran by kinds?

To conclude I think this PR should be closed as INVALID.
Comment 8 Steve Kargl 2014-12-02 17:29:01 UTC
On Tue, Dec 02, 2014 at 05:13:09PM +0000, dominiq at lps dot ens.fr wrote:
> 
> To conclude I think this PR should be closed as INVALID.
> 

That's the conclusion that I'm leaning towards.  Reading
section 16 of the standard always makes my head hurt, so
I'm being caution while looking for some subtle point 
that I may have missed.
Comment 9 Dominique d'Humieres 2014-12-02 17:36:11 UTC
> That's the conclusion that I'm leaning towards.  Reading
> section 16 of the standard always makes my head hurt, so
> I'm being caution while looking for some subtle point 
> that I may have missed.

And the threads I have pointed to are also convoluted. Now I find quite clear that using the same names for the dummy arguments in c_sub_cr and c_sub_rc does not permit to distinguish between c_sub_cr(num=x,z1=a) and c_sub_rc(num=x,z1=a), while using different names does.
Comment 10 Dominique d'Humieres 2014-12-06 15:03:20 UTC
The argument in comment 9 not being challenged, closing as INVALID.