Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Beginner
13 Views

Mixed-language compilation: printing floating point values in C produces errors in Fortran

I have a main Fortran code that calls a C library, and inside this C library, floating point values are written to the screen. The basic code is like this:

program fortran_main

  interface
    subroutine test_double_output(val) bind(c,name="TestDoubleOutput")
      use iso_c_binding, only: c_double
      implicit none
      real(c_double), value :: val
    end
  end interface

 call test_double_output(2.0d0)  ! Unexpected program exception

contains
  subroutine dummy()
  end subroutine   

end program

Code in the C library:

#include <iostream>

extern "C" {

void TestDoubleOutput(double val) {
  std::cout << "\nTestDoubleOutput was called: val = ";
  std::cout << val;           // This reproduces the error
  std::cout << ". OK\n";
}

}

 

When I compile with static debug libraries (/MTd and /libs:static) and /fpe-all:0, the above code gives this error: "forrtl: error (140): floating inexact". However, if I remove the "contains subroutine dummy()" section from the Fortran code, it prints the value as expected.

To get around this error (in the actual code, where I can't easily remove subroutines), I have found two solutions to the problem:

  1. remove /fpe-all:0, or
  2. use dynamic debug libraries (/MDd and /libs:dll)

I would really like to use static libraries with the /fpe-all:0 option if possible. Is there a reason that this combination does not work? I am using Visual Studio 2015 and Intel Fortran 17.0.4.201.

 

0 Kudos
4 Replies
Highlighted
Black Belt
13 Views

Here is one more alternative, if feasible: write the problematic subroutine(s) in the library in C (instead of in C++ with C linkage).

Are you using the VC/C++ compiler or the Intel C/C++ compiler?

0 Kudos
Highlighted
13 Views

To test call linkage

a) Change the argument to void (no argument) and comment out the cout of val.
b) Change the argument to int, and cout the val

Is your platform 32-bits or 64-bits?
On 32-bit systems, there can be compatibility issues of which floating point unit is used (FPU or VPU). This might be corrected by trying:

c) Change the argument from value double to reference double

Jim Dempsey

0 Kudos
Highlighted
Beginner
13 Views

@mecej4: I am using VC/C++, but this error also happens with Intel C/C++ compiler. I don't think it would be feasible to write the (actual) library in C instead of C++.

@jimdempseyatthecove: there is no error when using cout to print integers. When I print a floating point value, the debugger breaks on a line in C:\Program Files (x86)\Windows Kits\10\Source\10.0.10240.0\ucrt\convert\cfout.cpp, line 123:

int32_t k = static_cast<int32_t>(ceil(log10(value)));

I am compiling for Win32.

0 Kudos
Highlighted
13 Views

What happens when you change the argument to pass by reference? IOW avoid possible calling convention (on IA-32) as to if the 1st (only) argument is passed in register (with ambiguity as to if the register is in the FPU or VPU).

Jim Dempsey

0 Kudos