Fortran Coder

查看: 11144|回复: 9
打印 上一主题 下一主题

[面向对象] 过程绑定中的通用接口冲突问题

[复制链接]

79

帖子

17

主题

0

精华

专家

齊天大聖

F 币
433 元
贡献
266 点
跳转到指定楼层
楼主
发表于 2020-8-10 20:49:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 kyra 于 2020-8-11 08:44 编辑

[Fortran] 纯文本查看 复制代码
01module m_haha
02  implicit none
03  type t_haha
04     integer :: a
05   contains
06     procedure :: test1
07     procedure :: test2
08     procedure :: test3
09     generic :: test=>test1,test2,test3
10  end type t_haha
11contains
12  subroutine test1(this,i)
13    implicit none
14    class(t_haha),intent(inout) :: this
15    integer,intent(in) :: i
16 
17    this%a=i
18 
19    return
20  end subroutine test1
21 
22  subroutine test2(this,a)
23    implicit none
24    class(t_haha),intent(inout) :: this
25    integer,intent(in) :: a(0:3)
26 
27    this%a=sum(a)
28 
29    return
30  end subroutine
31  subroutine test3(this,a)
32    implicit none
33    class(t_haha),intent(inout) :: this
34    integer,intent(in) :: a(3)
35 
36    this%a=sum(a)
37 
38    return
39  end subroutine
40end module m_haha
41 
42program main
43  use m_haha
44  implicit none
45 
46  type(t_haha) :: one
47 
48 
49  call one%test1(1)
50  print*,one%a
51 
52  call one%test2([0,1,2,3])
53  print*,one%a
54 
55  call one%test3([1,2,3])
56  print*,one%a
57end program main

使用gfotran编译报错,错误原因,test2,test3接口冲突
改用pgi编译,正常。

很迷。。。。是我对重载的理解有问题吗?



分享到:  微信微信
收藏收藏 点赞点赞 点踩点踩

132

帖子

11

主题

0

精华

大师

F 币
625 元
贡献
377 点

贡献勋章管理勋章帅哥勋章元老勋章星光勋章规矩勋章

沙发
发表于 2020-8-10 21:50:54 | 只看该作者
Windows Absoft/Compaq/Intel/NAG/Silverfrost/NAG/G95 都是
test2,test3接口冲突: "test2" is not distinguishable (rank) from the "test3"

我認為PGI在這裡過於寬容

132

帖子

11

主题

0

精华

大师

F 币
625 元
贡献
377 点

贡献勋章管理勋章帅哥勋章元老勋章星光勋章规矩勋章

板凳
发表于 2020-8-10 23:05:15 | 只看该作者
[Fortran] 纯文本查看 复制代码
01module pgi_generic                                                                   
02  implicit none                                                                      
03                                                                                       
04  interface test                                                                     
05    module procedure test2                                                           
06    module procedure test3                                                           
07  end interface test                                                                 
08                                                                                       
09contains !------------------------------                                             
10                                                                                       
11  subroutine test2(a)                                                                
12    implicit none                                                                    
13    integer,intent(in) :: a(0:3)                                                     
14                                                                                       
15    write(*,*) a                                                                     
16  end subroutine test2                                                               
17                                                                                       
18  !-----------------                                                                 
19                                                                                       
20  subroutine test3(a)                                                                
21    implicit none                                                                    
22    integer,intent(in) :: a(3)                                                       
23                                                                                       
24    write(*,*) a                                                                     
25  end subroutine test3                                                               
26                                                                                       
27end module pgi_generic                                                               
28                                                                                       
29!---------------------------------------                                             
30                                                                                       
31program test                                                                         
32  use pgi_generic                                                                    
33  implicit none                                                                      
34                                                                                       
35  integer :: a(0:3), b(3)                                                            
36                                                                                       
37  a = (/0, 1, 2, 3/)                                                                 
38  b = (/4, 5, 6/)                                                                    
39                                                                                       
40  !---> PGI compile-time error: ambiguous interface for generic procedure test       
41  CALL test(a)                                                                       
42  CALL test(b)                                                                       
43                                                                                       
44end program test


PGI沒有一陸錯到底

132

帖子

11

主题

0

精华

大师

F 币
625 元
贡献
377 点

贡献勋章管理勋章帅哥勋章元老勋章星光勋章规矩勋章

地板
发表于 2020-8-10 23:06:46 | 只看该作者
抱歉, 是 "PGI沒有一路錯到底"

955

帖子

0

主题

0

精华

大师

F 币
188 元
贡献
77 点

规矩勋章元老勋章新人勋章水王勋章热心勋章

QQ
5#
发表于 2020-8-11 08:43:06 | 只看该作者
本帖最后由 kyra 于 2020-8-11 08:45 编辑

编译器在 generic name 中选择合适的interface procedure 调用。发生在编译时,而不是发生在运行时。
只有编译时能确定的区别,才能使用 generic name 重载。比如参数的类型,精度,数组维度,参数的个数,顺序。

而数组的大小,以及变量的值。在编译时无法确定。
比如
read(*,*) i , j
call test2( a(i:j) )
编译时无法确定 a 的大小。

顺带一提:你在m_haha里写了 implicit none ,那么这个module下面contains的procedure(test2 , test3)就不需要再写 implicit none 了。

132

帖子

11

主题

0

精华

大师

F 币
625 元
贡献
377 点

贡献勋章管理勋章帅哥勋章元老勋章星光勋章规矩勋章

6#
发表于 2020-8-11 14:45:00 | 只看该作者
1. 理應於"定義端"偵測到錯誤, PGI遲至"使用端"才說有錯

2. 被"CONTAINS", 透過所謂的"HOST ASSOCIATION", 繼承"IMPLICIT NONE"
    個人以為還是寫比較好, ...

79

帖子

17

主题

0

精华

专家

齊天大聖

F 币
433 元
贡献
266 点
7#
 楼主| 发表于 2020-8-11 16:42:42 | 只看该作者
vvt 发表于 2020-8-11 08:43
编译器在 generic name 中选择合适的interface procedure 调用。发生在编译时,而不是发生在运行时。
只有 ...

如果输入是a(:),那么出现ambiguous我认,但a(4),a(3)显然在编译的时候是应当可以被确定的。
module中的函数相当于给出了explicit,那么当实际输入变量大小和哑元大小不符合时就会报错,所以,为什么这个重载就不可以?

79

帖子

17

主题

0

精华

专家

齊天大聖

F 币
433 元
贡献
266 点
8#
 楼主| 发表于 2020-8-11 16:45:58 | 只看该作者
chiangtp 发表于 2020-8-10 21:50
Windows Absoft/Compaq/Intel/NAG/Silverfrost/NAG/G95 都是
test2,test3接口冲突: "test2" is not disti ...

感谢您回复,看起来PGI自己标准都不一致啊

955

帖子

0

主题

0

精华

大师

F 币
188 元
贡献
77 点

规矩勋章元老勋章新人勋章水王勋章热心勋章

QQ
9#
发表于 2020-8-11 17:42:44 | 只看该作者
lookbook 发表于 2020-8-11 16:42
如果输入是a(:),那么出现ambiguous我认,但a(4),a(3)显然在编译的时候是应当可以被确定的。
module中的 ...

你说的“实际输入变量大小和哑元大小不符合时就会报错”,是运行时错误,也是在运行时才做的检查。
但决定test实际调用的是test2还是test3,需要“编译时”就决定。

常规的 Type-Bound Procedures,都是编译时决定,调用哪个Procedure。
运行时决定的也有,类似C++的虚函数或者fortran的abstract interface。

79

帖子

17

主题

0

精华

专家

齊天大聖

F 币
433 元
贡献
266 点
10#
 楼主| 发表于 2020-8-11 19:25:44 | 只看该作者
vvt 发表于 2020-8-11 17:42
你说的“实际输入变量大小和哑元大小不符合时就会报错”,是运行时错误,也是在运行时才做的检查。
但决 ...

我明白你的意思了,十分感谢!
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

捐赠本站|Archiver|关于我们 About Us|小黑屋|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2025-5-2 04:58

Powered by Discuz! X3.4

© 2013-2025 Comsenz Inc.

快速回复 返回顶部 返回列表