- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
program main implicit none integer(4),parameter:: lp = 4_4, ip = 4_4 integer(4):: i,j i = 52793874 j = i print*, anyiseq(i,j) print*, anyiseq2(i,j) contains !--compare two scalar byte by byte elemental logical(lp) function anyiseq(lhs,rhs) result(r) class(*),intent(in):: lhs,rhs integer(1),dimension(sizeof(lhs)):: lb integer(1),dimension(sizeof(rhs)):: rb integer(ip):: i r = .false. if(.not.same_type_as(lhs,rhs)) return if(.not.size(lb)==size(rb)) return lb = transfer(lhs,mold=lb) rb = transfer(rhs,mold=rb) r = all(lb==rb) end function anyiseq !--compare two scalar byte by byte logical(lp) function anyiseq2(lhs,rhs) result(r) class(*),intent(in):: lhs,rhs character(len=sizeof(lhs),kind=1):: lb character(len=sizeof(rhs),kind=1):: rb integer(ip):: i r = .false. if(.not.same_type_as(lhs,rhs)) return if(.not.len(lb)==len(rb)) return lb = transfer(lhs,mold=lb) rb = transfer(rhs,mold=rb) r = lb == rb end function anyiseq2 end program main
here i compare two unlimited polymorphism types byte by byte
i tested two methods with debug mode, and i received <access violation> for the second one at line
lb = transfer(lhs,mold=lb)
is this a bug or i missed something?
i use the vs2015+ifort2017u4
and more
for now, i just have tested this function for some simple derived type.
i wonder anyone have experience about this method and knows whether it's a proper way to compare any types
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think the issue here is that the Fortran language does not require the Fortran processor to be able to construct a derived type from an unlimited polymorphic descriptor at run time the way that interpreted languages such as Matlab can. Since the processor doesn't know how to construct the type in the specification part of the procedures, it has no way of knowing what SIZEOF(lhs) should return, for example. Thus ifort should simply produce an error at compile time. That's why you need a SELECT TYPE construct to do much with an unlimited polymorphic entity, however you can't put a SELECT TYPE construct in the specification part of a procedure, and besides SELECT TYPE kind of takes all the fun out of unlimited polymorphism.
When I remove the ELEMENTAL attribute from function anyiseq and print out SIZE(lhs) there and LEN(lhs) in function anyiseq2, ifort 16.0 prints out 0 in both cases. gfortran 5.3 just hangs at runtime without reaching the WRITE statements. Thus there isn't any problem with TRANSFER in function anyiseq because the size of the MOLD= array is ignored, but there is a problem in function anyiseq2 because of the CHARACTER(LEN=0) MOLD= argument to TRANSFER. Actually, this runs to completion in ifort 16.0, so this may be a regression in ifort2017u4. What happens if you try something like
program P implicit none character(LEN=0) C type T sequence end type T type(T) A write(*,*) F(C,A) contains function F(X,Y) integer F character(LEN=*) X type(T) Y X = TRANSFER(Y,X) F = INDEX(X,'A') end function F end program P
Does this also cause an access violation?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Repeat Offender wrote:
I think the issue here is that the Fortran language does not require the Fortran processor to be able to construct a derived type from an unlimited polymorphic descriptor at run time the way that interpreted languages such as Matlab can. Since the processor doesn't know how to construct the type in the specification part of the procedures, it has no way of knowing what SIZEOF(lhs) should return, for example. Thus ifort should simply produce an error at compile time. That's why you need a SELECT TYPE construct to do much with an unlimited polymorphic entity, however you can't put a SELECT TYPE construct in the specification part of a procedure, and besides SELECT TYPE kind of takes all the fun out of unlimited polymorphism.
When I remove the ELEMENTAL attribute from function anyiseq and print out SIZE(lhs) there and LEN(lhs) in function anyiseq2, ifort 16.0 prints out 0 in both cases. gfortran 5.3 just hangs at runtime without reaching the WRITE statements. Thus there isn't any problem with TRANSFER in function anyiseq because the size of the MOLD= array is ignored, but there is a problem in function anyiseq2 because of the CHARACTER(LEN=0) MOLD= argument to TRANSFER. Actually, this runs to completion in ifort 16.0, so this may be a regression in ifort2017u4. What happens if you try something like
program P implicit none character(LEN=0) C type T sequence end type T type(T) A write(*,*) F(C,A) contains function F(X,Y) integer F character(LEN=*) X type(T) Y X = TRANSFER(Y,X) F = INDEX(X,'A') end function F end program PDoes this also cause an access violation?
sizeof(lhs) gives the right answer (4), by ifort2017u4
it seems <size> and <len> don't work for class(*), but not including <sizeof>
your code runs well and no access violation. it prints 0.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Li L
Should your type contain an allocatable component, the byte-by-byte compares will be comparing the array descriptors and not the contents of the identical contented arrays. Thus identical types will fail equality test.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
thanks for your advice
and i will pay attention to the limitation of this function
and can you reproduce the access violation and knows why?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Li L. wrote:
thanks for your advice
and i will pay attention to the limitation of this function
and can you reproduce the access violation and knows why?
Try using standard intrinsic function STORAGE_SIZE: https://software.intel.com/en-us/fortran-compiler-18.0-developer-guide-and-reference-storage-size
Look into CHARACTER_STORAGE_SIZE and NUMERIC_STORAGE_SIZE also in connection with this: https://software.intel.com/en-us/fortran-compiler-18.0-developer-guide-and-reference-named-constants-1
Also, post at Intel's Online Service Center (OSC) to get an answer from Intel staff as to why the access violation occurs: https://software.intel.com/en-us/articles/how-to-create-a-support-request-at-online-service-center.
Separately, though, you may want to rethink what you're trying to do and ask yourself whether you really need functions such as the two you show; for intrinsic types, use intrinsic capabilities and for your derived types, can you not include defined comparison operators? By the way, I suggest staying from SEQUENCE types if you can.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
FortranFan wrote:
Quote:
Li L. wrote:
thanks for your advice
and i will pay attention to the limitation of this function
and can you reproduce the access violation and knows why?
Try using standard intrinsic function STORAGE_SIZE: https://software.intel.com/en-us/fortran-compiler-18.0-developer-guide-a...
Look into CHARACTER_STORAGE_SIZE and NUMERIC_STORAGE_SIZE also in connection with this: https://software.intel.com/en-us/fortran-compiler-18.0-developer-guide-a...
Also, post at Intel's Online Service Center (OSC) to get an answer from Intel staff as to why the access violation occurs: https://software.intel.com/en-us/articles/how-to-create-a-support-reques....
Separately, though, you may want to rethink what you're trying to do and ask yourself whether you really need functions such as the two you show; for intrinsic types, use intrinsic capabilities and for your derived types, can you not include defined comparison operators? By the way, I suggest staying from SEQUENCE types if you can.
as your advice, i'm refactoring my code
i'm just practicing the structure of hashmap
for the first time, i want to use the class(*) for simplicity, and write the function above
but now, i think i can just transfer all of possible data(just simple derived type and native type) to integer array
and integer's operator(==) is much faster than character's operator(==)
SEQUENCE is a good advice
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page