Mixing C, C++, and Fortran: A Brief Overview

It is possible to build programs using a mixture of C, C++, and Fortran code. There are some pitfalls, however. The details of mixing languages are beyond the scope of this manual, but a few examples are provided here to introduce the general idea.

Data formats

One major issue for scientific programmers is the structure of multidimensional arrays. C and C++ use row-major format (all elements of a given row are stored contiguously in memory), while Fortran uses column-major format (all elements of a given column are contiguous).

Hence, matrix[row][col] in C or C++ is represented as matrix(col,row) in Fortran.

This is just one of many differences in how data structures differ between C/C++, and Fortran. More information can be found on the web by searching for "mixing C and Fortran".

Libraries

Fortran compilers typically decorate or mangle symbol names with the program by appending an underscore character. Hence, a Fortran function called invert() would be called as invert_() from within a C or C++ program.

Calling C functions from within a Fortran or C++ program doesn't generally require and special effort. Hence, it is often easier to use the Fortran or C++ compiler for the link phase when building a mixed-language program that calls C functions.

This could, however, result in "undefined symbol" errors, since a Fortran compiler will not search the standard C libraries by default. If calling standard C library functions from a Fortran program, you may need to add -lc to the link command, so that the Fortran linker will search the standard C library, libc.so.

Examples

The example makefiles below show how to build programs with various mixtures of C, C++, and Fortran. If you are not familiar with makefiles, you may want to read Chapter 21, Building with Make first.

BIN     = program
OBJS    = main.o functions.o

# Use the same tool chain for all builds to avoid issues
CC      = gcc
CFLAGS  = -Wall -O -g
FC      = gfortran
FFLAGS  = ${CFLAGS}

# Use Fortran compiler to link to avoid name mangling issues
LD      = ${FC}
LDFLAGS = -lc

# Link
program:    main.o functions.o
        ${LD} -o ${BIN} ${OBJS} ${LDFLAGS}

main.o: main.f90
        ${FC} -c ${FFLAGS} main.f90

functions.o:    functions.c
        ${CC} -c ${CFLAGS} functions.c
            

If calling C++ library functions from Fortran built with gfortran, link with -lstdc++ (the GNU C++ library).

BIN     = program
OBJS    = main.o functions.o

# Use the same tool chain for all builds to avoid issues
CXX         = g++
CXXFLAGS    = -Wall -O -g
FC          = gfortran
FFLAGS      = ${CXXFLAGS}

# Use Fortran compiler to link to avoid name mangling issues
LD      = ${FC}
LDFLAGS = -lstdc++

# Link
program:    main.o functions.o
        ${LD} -o ${BIN} ${OBJS} ${LDFLAGS}

main.o: main.f90
        ${FC} -c ${FFLAGS} main.f90

functions.o:    functions.cc
        ${CXX} -c ${CXXFLAGS} functions.cc
            

If calling Fortran library functions from C or C++ with the GNU compiler collection, add -lgfortran.

BIN     = program
OBJS    = main.o functions.o

# Use the same tool chain for all builds to avoid issues
CC      = gcc
CFLAGS  = -Wall -O -g
FC      = gfortran
FFLAGS  = ${CFLAGS}

# Use C compiler to link, since the main program is in C
LD      = ${CC}
LDFLAGS = -lgfortran

# Link
program:    main.o functions.o
        ${LD} -o ${BIN} ${OBJS} ${LDFLAGS}

main.o: main.c
        ${CC} -c ${CFLAGS} main.c

functions.o:    functions.f90
        ${FC} -c ${FFLAGS} functions.f90
            

If calling C++ library functions from Fortran built with gfortran, link with -lstdc++ (the GNU C++ library).

BIN     = program
OBJS    = main.o functions.o

# Use the same tool chain for all builds to avoid issues
CXX         = g++
CXXFLAGS    = -Wall -O -g
FC          = gfortran
FFLAGS      = ${CXXFLAGS}

# Use Fortran compiler to link to avoid name mangling issues
LD      = ${FC}
LDFLAGS = -lstdc++

# Link
program:    main.o functions.o
        ${FC} -o ${BIN} ${OBJS} ${LDFLAGS}

main.o: main.f90
        ${FC} -c ${FFLAGS} main.f90

functions.o:    functions.cc
        ${CXX} -c ${CXXFLAGS} functions.cc
            
Practice

Note

Be sure to thoroughly review the instructions in Section 2, “Practice Problem Instructions” before doing the practice problems below.
  1. Can we mix C, C++, and Fortran source code in the same makefile? Explain.