- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
A Fortran function, REDUCE, is called from C++. The return value of the Fortran function is a user-defined type, Rational.
In CVF6.6, the code shown below works correctly. In IF9.1, there is a link error, because the C++ function prototype for Reduce has 2 args, and the compiler generates code for 1. In CVF6.6, the extra "argument" was a pointer to the memory where the function's return value was to be stored.
How can I store the Fortran function's return value in my C++ caller?
The Fortran module:
MODULE RationalArithmetic
IMPLICIT NONE
PRIVATE
PUBLIC :: rational
TYPE rational
PRIVATE
INTEGER :: num,denom
END TYPE rational
CONTAINS
TYPE(rational) ELEMENTAL FUNCTION Reduce(rat)
TYPE(rational), INTENT(IN) :: rat
[code which sets Reduce%num and Reduce%denom]
END FUNCTION Reduce
END MODULE RationalArithmetic
The C++ caller:
extern "C" void __stdcall RATIONALARITHMETIC_mp_REDUCE(Rational *rat1, Rational *rat);
RATIONALARITHMETIC_mp_REDUCE(&s/*Fortran function return*/, &s);
In IF9.1.025, the the compiler generates code that includes
_TEXT SEGMENT DWORD PUBLIC FLAT 'CODE'
; -- Begin _RATIONALARITHMETIC_mp_REDUCE@4
; mark_begin;
ALIGN 2
PUBLIC _RATIONALARITHMETIC_mp_REDUCE@4
_RATIONALARITHMETIC_mp_REDUCE@4 PROC NEAR
PUBLIC _RATIONALARITHMETIC_mp_REDUCE
_RATIONALARITHMETIC_mp_REDUCE::
; parameter 1(REDUCE): 8 + ebp
; parameter 2(RAT): 12 + ebp
$B22$1: ; Preds $B22$0
;;; TYPE(rational) ELEMENTAL FUNCTION Reduce(rat)
In CVF6.6, the code shown below works correctly. In IF9.1, there is a link error, because the C++ function prototype for Reduce has 2 args, and the compiler generates code for 1. In CVF6.6, the extra "argument" was a pointer to the memory where the function's return value was to be stored.
How can I store the Fortran function's return value in my C++ caller?
The Fortran module:
MODULE RationalArithmetic
IMPLICIT NONE
PRIVATE
PUBLIC :: rational
TYPE rational
PRIVATE
INTEGER :: num,denom
END TYPE rational
CONTAINS
TYPE(rational) ELEMENTAL FUNCTION Reduce(rat)
TYPE(rational), INTENT(IN) :: rat
[code which sets Reduce%num and Reduce%denom]
END FUNCTION Reduce
END MODULE RationalArithmetic
The C++ caller:
extern "C" void __stdcall RATIONALARITHMETIC_mp_REDUCE(Rational *rat1, Rational *rat);
RATIONALARITHMETIC_mp_REDUCE(&s/*Fortran function return*/, &s);
In IF9.1.025, the the compiler generates code that includes
_TEXT SEGMENT DWORD PUBLIC FLAT 'CODE'
; -- Begin _RATIONALARITHMETIC_mp_REDUCE@4
; mark_begin;
ALIGN 2
PUBLIC _RATIONALARITHMETIC_mp_REDUCE@4
_RATIONALARITHMETIC_mp_REDUCE@4 PROC NEAR
PUBLIC _RATIONALARITHMETIC_mp_REDUCE
_RATIONALARITHMETIC_mp_REDUCE::
; parameter 1(REDUCE): 8 + ebp
; parameter 2(RAT): 12 + ebp
$B22$1: ; Preds $B22$0
;;; TYPE(rational) ELEMENTAL FUNCTION Reduce(rat)
Link Copied
2 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I can confirm that this is a difference, albeit one I was not aware of before. It is also documented, though in a place you'd never think to look for it (in the section on mixing MASM and Fortran). It also matches the C behavior with structs. User defined types of 8 bytes or less are returned in the EAX or EAX:EDX registers.
I'll ask that the documentation in this area be enhanced.
I'll ask that the documentation in this area be enhanced.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can adjust the code in either the Fortran or C++ side to account for this difference. On the Fortran side, make it a subroutine with an extra first argument, and on the C++ side, make it a function returning a struct.
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