Skip to content

scivision/fortran-cpp-interface

Folders and files

NameName
Last commit message
Last commit date

Latest commit

df39841 · Mar 4, 2025
Mar 4, 2025
May 7, 2024
Feb 28, 2025
Dec 25, 2022
Aug 5, 2024
Feb 28, 2025
Feb 28, 2025
May 21, 2024
Sep 7, 2020
Jan 27, 2025
Aug 16, 2023
Dec 30, 2022
May 20, 2024
Mar 6, 2023

Repository files navigation

Interoperability examples between C, C++ and Fortran

ci oneapi-linux

Fortran subroutines and functions are easily called from C and C++.

Use the standard C binding to define variable and bind functions/subroutines.

This project is also a way to quickly check if compilers you have are ABI-compatible. For example:

  • Clang and Gfortran
  • (Windows) MSVC and Intel oneAPI ifx

Demonstrate linking of

  • C and C++ program calling Fortran libraries
  • Fortran program calling C and C++ libraries

We assume the compilers are C++20 and Fortran 2018 capable.

This repo's examples are also known to work with:

  • NVidia HPC SDK (nvc++, nvfortran)
  • AOCC AMD Optimizing Compliers
  • Cray compilers (cc, ftn)

In general, avoid the FortranCInterface of CMake and mangling function names. Instead, use Fortran 2003 standard bind(C).

Other real-world examples include fortran-filesystem using C++ stdlib filesystem from Fortran and standard sleep implementation as used in blocktran and Fortran Standard Library.

Build

cmake -B build

cmake --build build

ctest --test-dir build

Note the use of CMake target property LINKER_LANGUAGE necessary for CMake with Intel oneAPI or NVIDIA HPC SDK on Linux.

  • C main program with Fortran library: LINKER_LANGUAGE C
  • C++ main program with Fortran library: LINKER_LANGUAGE CXX
  • Fortran main program with C or C++ library: LINKER_LANGUAGE Fortran
add_executable(f_main main.f90 lib.cpp)
set_property(TARGET f_main PROPERTY LINKER_LANGUAGE Fortran)

add_executable(c_main main.c lib.f90)
set_property(TARGET c_main PROPERTY LINKER_LANGUAGE C)

add_executable(cpp_main main.cpp lib.f90)
set_property(TARGET cpp_main PROPERTY LINKER_LANGUAGE CXX)

Examples

While the examples prioritize C++, there are also several companion C examples to go with the C++ examples. There are also some Fortran main programs calling C or C++.

arrays

The examples "array", "malloc", "vector" show distinct ways to send arrays to/from Fortran with C and C++.

bool

nvfortran supports F2018 standard C_BOOL if nvfortran -Munixlogical is used.

The logical constants .TRUE. and .FALSE. are defined to be the four-byte values -1 and 0 respectively. A logical expression is defined to be .TRUE. if its least significant bit is 1 and .FALSE. otherwise.

Example output, Fortran interfacing with C or C++

  • Intel oneAPI 2023 without -fpscomp logicals
  • NVHPC 2023.5 without -Munixlogical
 logical_not(T): F
   storage_size()  bits   hex(in)  hex(out)
         C_BOOL:     8         1        FE
 logical_not(true) should be false: 1

 logical_not(F): T
   storage_size()  bits   hex(in)  hex(out)
         C_BOOL:     8         0        FF
  • Intel oneAPI 2023 with -fpscomp logicals
  • NVHPC 2023.5 with -Munixlogical
 logical_not(T): F
   storage_size()  bits   hex(in)  hex(out)
         C_BOOL:     8         1         0

 logical_not(F): T
  storage_size()  bits   hex(in)  hex(out)
        C_BOOL:     8         0         1
 OK: boolean-logical not

Error handling

Using Fortran statement "stop" or "error stop" with a C/C++ main program works like with a Fortran main program. The "error" examples show this.

ISO_Fortran_binding.h

On 2019-01-12 a GCC commit from Paul Thomas brought ISO_Fortran_binding.h to GCC 9.

This means if using Clang compiler e.g. on macOS, you may need to switch to GCC (till Clang/Flang someday includes ISO_Fortran_binding.h).

Compilers having "ISO_Fortran_binding.h" include:

  • GCC ≥ 9
  • Intel oneAPI
  • Clang / Flang LLVM ≥ 19
  • IBM OpenXL
  • Cray Fortran

Notes

struct memory alignment

Some examples use scalar C struct. ISO_C_BINDING handles mapping struct to/from Fortran TYPE. For arrays of struct, compiler pragma may be needed.

Valgrind needed suppression to avoid memory alignment (uninitialized memory) warnings for C struct input to nanosleep.

MacOS

For MacOS with Apple's Clang and Homebrew GCC, it MAY be needed to have in ~/.zshrc like the following: (check directory / versions on your Mac)

export LIBRARY_PATH=$LIBRARY_PATH:/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib
export CPLUS_INCLUDE_PATH=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include
export CXXFLAGS=-I$CPLUS_INCLUDE_PATH
export CFLAGS=$CXXFLAGS

References