Fortran-to-C
March 29, 2026 ยท View on GitHub
xf2c.py is a Python source-to-source transpiler, developed with Codex, that converts a substantial subset of Fortran into readable C.
It is intended for:
- understanding and inspecting translated code
- building small and medium Fortran examples as C programs
- regression-testing Fortran and generated C side by side
- growing coverage incrementally from real Fortran codes
It is not positioned as a full Fortran compiler. It emits C source and then uses a C compiler such as gcc or clang.
Current Status
The project currently handles a broad practical subset of Fortran used in the example corpus in this repository, including:
program,module,use, contained proceduresfunction,subroutine, optional arguments, generic interfaces with module procedures- simple derived types, selected type-bound procedures, and selected operator overloading
allocatable,pointer,target,save,parameter- scalar and array expressions
- array constructors, array sections, lower bounds other than
1 size,shape,lbound,uboundsum,product,minval,maxval,count,any,all,dot_productspread,reshapeincludingorder=,packminloc,maxloc,findlocforall- scalar complex numbers and common complex intrinsics
- allocatable strings and many common CHARACTER operations
- list-directed output and a growing subset of formatted I/O
- stream I/O,
rewind, andbackspace select case, including character selectors and numeric ranges
Coverage is still incomplete. The project is driven by real examples, so unsupported features are added as they are encountered and generalized.
Requirements
- Python 3
- A Fortran compiler for
--run-bothor--compile-both- typically
gfortran
- typically
- A C compiler for generated C
gccis the default targetclangis also supportedcl.exesupport exists as an option, butgccis the primary target andclangis secondary
Main Files
- xf2c.py: thin CLI entry point
- xf2c_driver.py: CLI, build, run, and orchestration
- xf2c_core.py: main transpilation logic
- fortran_scan.py: scanning and validation
- fortran_runtime.c: shared C runtime helpers
- fortran_runtime.h: shared runtime declarations
- xc_post.py: conservative C readability cleanup
- xnormalize.py: output normalization used by
--pretty - xf2c_batch.py: cross-platform runner for many Fortran files
- xf2c_example_md.py: export a Fortran example, generated C, and both outputs to Markdown
Basic Usage
Generate C:
python xf2c.py xhello.f90
Write generated C to stdout as well:
python xf2c.py xhello.f90 --tee
Compile generated C:
python xf2c.py xhello.f90 --compile
Compile and run generated C:
python xf2c.py xhello.f90 --run
Build and run both the original Fortran and the generated C:
python xf2c.py xhello.f90 --run-both
Normalize displayed output from both runs for easier comparison:
python xf2c.py xhello.f90 --run-both --pretty
Output Files
By default, generated C is written as:
temp_<source-stem>.c
Examples:
xhello.f90->temp_xhello.cxstream.f90->temp_xstream.c
Use --out to choose the output filename explicitly:
python xf2c.py xhello.f90 --out hello_transpiled.c
Useful Options
--tee print generated C
--compile compile generated C
--compile-c compile generated C only, no link
--run compile and run generated C
--run-both run original Fortran and generated C
--compile-both build original Fortran and generated C
--one-line collapse simple one-statement C blocks
--annotate add original-Fortran comments before translated code
--raw disable C postprocessing
--single-file embed runtime helpers directly into the generated C file
--clang compile generated C with clang
--msvc compile generated C with cl.exe
--pretty normalize displayed run output only
--no-validate skip pre-validation
Examples:
python xf2c.py xmean_sd.f90 --run-both --pretty
python xf2c.py xreturns.f90 --compile --tee
python xf2c.py xstream.f90 --single-file --run
python xf2c.py xcomplex.f90 --compile --clang
Raw vs Postprocessed C
By default, generated C is postprocessed for readability.
That cleanup currently does conservative transformations such as:
- removing dead loop labels
- simplifying constant integer expressions
- reducing redundant parentheses
- consolidating declarations
- improving generated temporary names
To see the raw transpiler output:
python xf2c.py xsum_dim.f90 --raw --tee
Shared Runtime vs Single File
By default, generated programs include and link the shared runtime:
This keeps emitted C shorter and more readable.
If you want one standalone generated C file:
python xf2c.py xread.f90 --single-file
Running Many Examples
Run several files directly:
python xf2c_batch.py xhello.f90 xlogical.f90
Use an optional manifest file:
python xf2c_batch.py --file-list fortran_files.txt
Limit how many files are processed:
python xf2c_batch.py --file-list fortran_files.txt --limit 5
The default xf2c.py options used by the batch runner are:
--run-both --tee
Override them if needed:
python xf2c_batch.py xhello.f90 --opts "--compile"
Example
- xreturns_stats.md: example page showing the Fortran source, generated C, and both outputs for a program that reads stock prices and computes returns statistics and correlations. Many other examples are here.
What Works Well Today
The project is strongest on:
- numerically oriented procedural code
- arrays and common array intrinsics
- string handling used in practical examples
- small module-based programs
- source inspection and debugging of translated output
The generated C is intended to be readable, especially with the default postprocessing enabled.
Current Limitations
This is still a subset transpiler. You should expect gaps.
Known limits include:
- some formatted I/O patterns are still unsupported
- some advanced module and interface cases still need work
- polymorphic and richer object-oriented Fortran is only partially handled
- support is much stronger for free-form Fortran than for older fixed-form code
gccis the primary supported C compiler;clangis useful;msvcis not a current priority
If a construct is unsupported, the transpiler usually emits a clear validation or /* unsupported: ... */ marker showing what still needs lowering.
Recommended Workflow
For a new example:
- Run:
python xf2c.py your_file.f90 --run-both --pretty
-
If validation fails, fix or extend the transpiler.
-
If C builds but output differs, inspect:
python xf2c.py your_file.f90 --run-both
python xf2c.py your_file.f90 --tee
- Keep a small regression example and rerun it after each extension.
Project Direction
The long-term goal is broad practical coverage of Fortran-to-C translation while keeping generated C understandable.
This project is best thought of as:
- a Fortran-to-C transpiler
- a source-to-source compiler in workflow style
but not a replacement for a full native Fortran compiler.