Home Objexx Engineering

Fortran to C++ Conversion: Objexx F2C++

Objexx Engineering provides Fortran to C++ conversions using a sophisticated process and our F2C++ tools. The goal of our conversion is to preserve the syntax and semantics of the Fortran within fully ANSI/ISO compliant C++ to preserve the value of the code and existing documentation and to allow a wide range of developers to maintain the code.

Conversion Benefits and Tradeoffs

Conversion to C++ can be the right choice for a project in a number of situations. C++ is a more powerful language with better object-oriented design support and a much larger pool of developers to draw from. C++ also has a vast range of libraries and excellent GUI, visualization, and plotting packages to choose from.

Conversion vs. Wrapping

It is possible to get many of these benefits by wrapping a Fortran computational core in a modern C++ application, and Objexx uses this approach for some projects, but the burden of maintaining the C++—Fortran interface and the additional complexity of a hybrid application are often not warranted.

Performance

Performance impacts of a conversion to C++ can be minimal in most cases. Despite the use of efficient ObjexxFCL arrays the as-converted C++ is likely to be somewhat slower than the Fortran until some tuning of performance-critical code is performed. The ObjexxFCL arrays have a built-in fast lookup method that can go a long way towards bringing the speed back in line with that of the Fortran, or in some cases exceeding it.

When Performance considerations are important Objexx can do a small conversion+tuning study on sample code to demonstrate the performance of the C++ vs. that of the Fortran.

Technical Notes

Some of the technical aspects of our conversion include:

  • Reference (not pointer!) argument passing for clean code that corresponds to the Fortran
  • Variable names and comments are preserved
  • Fortran-like array template classes provide column-major arrays that preserve the element indexing of the Fortran and Fortran's array passing "tricks"
  • Fortran-like string and substring classes are provided to encapsulate the distinct properties of Fortran strings and allow these strings to work smoothly with C++ strings
  • DATA statements become constructor initializers
  • PARAMETER, SAVE, VOLATILE, INTENT and other Fortran declaration attribute semantics are preserved
  • COMMON blocks are converted to namespaces
  • EQUIVALENCEs and COMMONs that can introduce aliasing are detected and converted as appropriate for the intent of the usage

The Objexx Fortran Compatibility Library (ObjexxFCL) that provides the array, string, and intrinsic function support is open source: it is included in C++ source form with licensing that allows modification by the clients. The ObjexxFCL is in use in major codes and has been heavily tested and vetted for correctness. The ObjexxFCL arrays provide high-performance tuning capabilities and some unique dynamic sizing capabilities that can be exploited to great effect in meeting post-conversion modernization and refactoring goals.

Conversion Sample

This conversion of a simple Fortran 77 routine to C++ (shown at right) gives some sense of our approach. The philosophy of this method is to maintain the syntax and semantics of the Fortran as much as possible, thereby allowing both C++ and Fortran developers to maintain the code.






Fortran Subroutine

!============================================
! Multiply Matrix by Vector: b = A x
!============================================
  SUBROUTINE MULTAX( M, N, A, X, B )

  INTEGER, INTENT(IN) :: M, N
  REAL, INTENT(IN) :: A(M,N) ! Matrix
  REAL, INTENT(IN) :: X(N) ! Vector
  REAL, INTENT(INOUT) :: B(M) ! Vector Out

  INTEGER I, J
  REAL BI

  ! Compute b = A x
  DO I = 1, M
     BI = 0.0
     DO J = 1, N
        BI = BI + A(I,J) * X(J)
     END DO
     B(I) = BI
  END DO

  END

C++ Conversion

#include "multAx.h"
#include "FArray.h"

//===========================================
// Multiply Matrix by Vector: b = A x
//===========================================
void
MULTAX(
 int M,
 int N,
 FArray2D_f const & A, // Matrix
 FArray1D_f const & X, // Vector
 FArray1D_f & B // Vector Out
)
{
   // Compute b = A x
   for ( int I = 1; I <= M; ++I ) {
      float BI = 0.0;
      for ( int J = 1; J <= N; ++J ) {
         BI += A(I,J) * X(J);
      }
      B(I) = BI;
   }
}