Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28469 Discussions

Does /warn:interfaces change calling conventions? Qsort sample with derived types.

rwg
Beginner
435 Views
Following code works fine if it is compiled with /warn:interfaces:

[bash]      MODULE TEST__MOD
       TYPE T_DAT
        CHARACTER(16) NAME
        CHARACTER(24) DESC
        INTEGER       IHND
       ENDTYPE T_DAT
      ENDMODULE TEST__MOD
      
      
      PROGRAM TESTPRJ_FORTRAN
      USE TEST__MOD
      USE IFPORT
      INTERFACE
        SUBROUTINE QSORT_DAT( ARRAY, LEN, ISIZE, COMPDAT )
        USE TEST__MOD
      !DEC$ ATTRIBUTES DEFAULT,DECORATE,ALIAS:'QSORT' ::  QSORT_DAT
           INTEGER LEN, ISIZE
           TYPE (T_DAT) ARRAY(*)
           INTEGER(2), EXTERNAL :: COMPDAT
        END SUBROUTINE
      END INTERFACE
      INTEGER LEN
      INTEGER ISIZE
      INTEGER(2),EXTERNAL:: COMPDAT
      TYPE (T_DAT),ALLOCATABLE:: DAT(:)
!      
      ALLOCATE(DAT(26))
      DO I=1,26
       DAT(I)%NAME=CHAR(ICHAR('Z')-I+1)
       DAT(I)%DESC="Descrpition"
       DAT(I)%IHND=0
      ENDDO
      ISIZE = SIZEOF(DAT(1))
      LEN=SIZE(DAT)
      CALL QSORT_DAT(DAT, LEN, ISIZE, COMPDAT)
      DO I=1,LEN
       WRITE(*,*) DAT(I)%NAME
      ENDDO
      READ(*,*) LEN
      END PROGRAM TESTPRJ_FORTRAN



      INTEGER(2) FUNCTION COMPDAT(DAT1,DAT2)
!DEC$ ATTRIBUTES C,ALIAS:'_COMPDAT'::COMPDAT
!DEC$ ATTRIBUTES REFERENCE::DAT1
!DEC$ ATTRIBUTES REFERENCE::DAT2
      USE TEST__MOD
      TYPE(T_DAT) DAT1
      TYPE(T_DAT) DAT2
      IF(DAT1%NAME.LT.DAT2%NAME) THEN
       COMPDAT=-1
      ELSEIF(DAT1%NAME.EQ.DAT2%NAME) THEN
       COMPDAT=0
      ELSE
       COMPDAT=1
      ENDIF
      ENDFUNCTION COMPDAT


[/bash]
Removing switch /warn:interfaces causes following runtime error:
forrtl: severe (157): Program Exception - access violation

I thought /warn:interface does not change the obj-file of the compiler but this seems to be wrong.

Here my other compiler options:

/nologo /debug:full /Od /gen-interfaces /iface:cvf /module:"Debug\\\\" /object:"Debug\\\\" /traceback /check:bounds /libs:static /threads /dbglibs /c

I'm using Version Intel Visual Fortran 11.1.065 [IA-32]

By the way, what's the best solution to call qsort with derived types?

0 Kudos
8 Replies
mecej4
Honored Contributor III
435 Views
With IFORT 11.1.065, I find no errors with or without /warn:interfaces. Both times, the program printed out the alphabet.
0 Kudos
Steven_L_Intel1
Employee
435 Views
I can't reproduce this problem. /warn:interface isn't supposed to change the code at all, though I have seen cases in the past where it did.

Your example seems to do a fine job calling QSORT with a derived type. IFPORT declares QSORT as a generic, which you can extend, but the way you did it is ok.
0 Kudos
rwg
Beginner
435 Views
That's very strange.

At home on my notebook (with a fresh IVF installation under Windows 7) I made a new project and I also can not reproduce this problem.

At the office (with updated versions of IVF) I can reproduce the error on 3 different PCs (Windows XP and Windows 7).

When I replacing COMPDAT with a c-functions or linking the release Version the error is gone too. Switching calling convention from default do CVF under the release configuration an other error occurs. (But that's perhaps another problem.)

At last I added /VERBOSE to the link options and found that different functions are loaded.
With switch /warn:interfaces _cpstr is found instead of _cpystr and memcpy_largest_cache size instead of memcpy_mem_ops_method which perhaps explains the different behaviour. But it does not explain why this depends on the switch /warn:interfaces.

I added my project files and the output of the linker so I hope you can reproduce these effects.
0 Kudos
Steven_L_Intel1
Employee
435 Views
I'm not seeing any errors in the "error" text file.
0 Kudos
rwg
Beginner
435 Views
Sorry, I forgot to mention that output_ok.txt is the linker output with switch /warn:interfaces and output_error.txt is the linker output without switch /warn:interfaces. If this switch does not change the code, both files should be identical, but they aren't. In linker_output_ok.txt _cpstr is linked (referenced from qsort.obj in libifcoremt.lib) but in linker_output_ok.txt _cpystr is linked (also referenced from qsort.obj in libifcoremt.lib). This perhaps explains the memory corruption at the second(!) call of COMPDAT when I don't use the switch /warn:interfaces. But I think I've to find a reproduceable example first. Because my application works fine after replacing COMPDAT with a c-function it's no more urgent.
Thanks for your support.
0 Kudos
Steven_L_Intel1
Employee
435 Views
I can reproduce an error with or without /warn:interface. I'll look into it further and let you know what I find.
0 Kudos
Steven_L_Intel1
Employee
435 Views
I finally figured out what was going on here. The key point I had missed was that your project had a file-specific property for the source that set /iface:cvf. This shouldn't have mattered because you added ATTRIBUTES C for the COMPDAT routine, but the compiler saw a reference to COMPDAT in the main program and, at the time, since it was operating in "CVF" mode, recorded in its symbol table that COMPDAT should be a "CVF" routine, ignoring that you changed that later. This is a bug.

The workaround is to add:

!DEC$ ATTRIBUTES DEFAULT :: COMPDAT

right after the EXTERNAL declaration of COMPDAT in the main program (not in the interface block, where you already have a directive for it.)

/warn:interface doesn't, I think, have much to do with this.

I will report this to the developers. My apologies for it taking so long. Issue ID is DPD200158473.
0 Kudos
Steven_L_Intel1
Employee
435 Views
The fix for this was complicated, so it took us a while. I expect the fix to appear in update 2 to Fortran Composer XE 2011.
0 Kudos
Reply