macOS Apple Silicon
fortsh on Apple Silicon (M1/M2/M3/M4) uses a C string backend to work around Fortran compiler bugs on ARM64.
Background
gfortran Issues
gfortran on ARM64 macOS has multiple severe bugs:
- Stack corruption with programs using more than ~600KB stack
- Deferred-length string length loss during argument passing
- Segfaults on
intent(out)string arguments - Heap corruption on string assignment
These bugs make gfortran unusable for fortsh on Apple Silicon.
flang-new Workaround
fortsh uses flang-new (LLVM's Fortran compiler) on Apple Silicon. Older versions of flang-new had a 128-byte substring bug that caused heap corruption, but this is now worked around by the C string library.
C String Library
Since v1.1.0, fortsh includes a C string backend (src/c_interop/) that implements all string operations in C, bypassing flang-new's string handling entirely. This is automatically enabled when building on macOS ARM64.
The C library handles:
- String allocation and deallocation via
malloc/free - All substring, copy, append, insert, and delete operations
- Safe buffer management with 1MB capacity limit per string
With the C string library enabled, the command line limit is 1024 characters. On Linux, the editing buffers are fully allocatable (no hard limit), but the C string backend on ARM uses fixed-capacity buffers capped at 1024.
Disabling the C String Library
If you need to build without it (not recommended):
make NO_C_STRINGS=1
Without it, the old 127-character command line limit applies.
Installation
Via Homebrew
brew install FortranGoingOnForty/tap/fortsh
From Source
# Install LLVM (provides flang-new)
brew install llvm
# Add to PATH
export PATH="/opt/homebrew/opt/llvm/bin:$PATH"
# Build (C string library is auto-enabled)
git clone https://github.com/fortrangoingonforty/fortsh.git
cd fortsh
make
sudo make install
The Makefile automatically detects ARM64, selects flang-new, and enables the C string library.
Configuration Differences
| Setting | Linux | macOS ARM64 |
|---|---|---|
| Editing buffers | Allocatable (no hard limit) | C string backend (1024 chars) |
| MAX_HISTORY | 1000 | 100 |
| String library | Native Fortran | C interop |
| Compiler | gfortran | flang-new |
Remaining Differences from Linux
- History is capped at 100 entries (vs 1000 on Linux) to reduce memory pressure
- Some internal operations use character-by-character copies instead of bulk assignment to avoid flang-new code generation issues
- Prompt formatting uses fixed-length buffers as an additional safety measure
Workarounds for Long Commands
If you hit the 1024-character limit (unlikely in practice):
Use Aliases
alias deploy='cd ~/projects/myapp && ./scripts/deploy.sh --env=prod'
Use Variables
export APP="$HOME/long/path/to/application"
cd "$APP"
Use Scripts
cat > script.sh << 'EOF'
# Your complex commands here
EOF
fortsh script.sh