Skip to main content

Command documentation sourced from the linux-command project This comprehensive command reference is part of the linux-command documentation project.

c89 - Standard C Language Compiler (C89)

The c89 command is a POSIX-compliant C language compiler that implements the C89 (ISO/IEC 9899:1990) standard. It serves as a standardized interface to C compilation as required by IEEE Std 1003.1-2001 ("POSIX.1"). On most modern systems, c89 is implemented as a wrapper around GCC that enforces C89 standard compliance, making it ideal for writing portable C code that adheres to the 1989 C standard. The compiler provides a consistent interface across different UNIX-like systems while maintaining strict adherence to the C89 specification.

Basic Syntax

c89 [-cEgs] [-D name[=value]] [-I directory] ... [-L directory] ...
[-o outfile] [-O optlevel] [-U name]... [-W 32|64] operand ...

Common Options

Compilation Control

  • -c - Compile source files but do not link (produce object files)
  • -E - Run preprocessor only, output to stdout
  • -o outfile - Specify output filename
  • -s - Strip symbolic information from executable

Debugging and Optimization

  • -g - Include debugging information in output
  • -O optlevel - Set optimization level (0=none, 1=basic, 2=more, 3=maximum)

Preprocessor Options

  • -D name[=value] - Define macro (defaults to 1 if no value)
  • -U name - Undefine macro
  • -I directory - Add directory to header file search path

Linking Options

  • -L directory - Add directory to library search path
  • -l library - Link with specified library

Architecture Options

  • -W 32|64 - Set pointer size to 32 or 64 bits

Usage Examples

Basic Compilation

Simple Program Compilation

# Compile and link single source file
c89 program.c

# Compile with custom output name
c89 -o myapp program.c

# Compile only (produce object file)
c89 -c program.c

# Compile with debugging information
c89 -g -o debug_app program.c

Multiple Source Files

# Compile multiple source files
c89 main.c utils.c helper.c -o application

# Compile separately then link
c89 -c main.c
c89 -c utils.c
c89 -c helper.c
c89 main.o utils.o helper.o -o application

# Compile with optimization
c89 -O2 -o optimized_app main.c utils.c

Preprocessor Usage

Macro Definition and Undefinition

# Define macros during compilation
c89 -DDEBUG -DVERSION=1.0 program.c

# Define for POSIX compliance
c89 -D_POSIX_C_SOURCE=200112L program.c

# Undefine problematic macros
c89 -Uunix -U__unix__ program.c

# Complex macro definitions
c89 -D'MAX_SIZE=1024' -D'OS_NAME="Unix"' program.c

Header File Management

# Add include directories
c89 -I./include -I/usr/local/include program.c

# Multiple include paths
c89 -Iinc -I../common -I/opt/project/include program.c

# Preprocessor only output
c89 -E program.c > program.i

# Preprocessor with macro expansion
c89 -E -dM program.c

Compilation Options

Optimization Levels

# No optimization (debug builds)
c89 -O0 -g -o debug_program program.c

# Basic optimization
c89 -O1 -o basic_opt program.c

# Standard optimization (recommended)
c89 -O2 -o standard_opt program.c

# Maximum optimization
c89 -O3 -o max_opt program.c

# Size optimization
c89 -Os -o size_opt program.c

Debugging and Profiling

# Include debug symbols
c89 -g -o debug_version program.c

# Include debug info with optimization
c89 -g -O2 -o opt_debug program.c

# Generate profiling information
c89 -pg -o profile_version program.c

# Strip symbols for production
c89 -s -o production program.c

Library Linking

Standard Libraries

# Link with math library
c89 -o calculator calc.c -lm

# Link with multiple libraries
c89 -o network_app net.c -lsocket -lnsl

# Custom library paths
c89 -L./lib -L/usr/local/lib -o app program.c -lmylib

# Static linking
c89 -static -o static_app program.c

# Dynamic linking
c89 -shared -o libmylib.so mylib.c

Project Organization

# Typical project compilation
c89 -I./include -L./lib -o myapp src/main.c -lmyproject -lm

# Compilation with library search
c89 -I../common/include program.c -L../common/lib -lcommon

# Build with dependency tracking
c89 -M -MF dependencies.d program.c

Advanced Compilation

Cross-compilation and Architecture

# Force 32-bit compilation on 64-bit system
c89 -W 32 -o app_32bit program.c

# Force 64-bit compilation
c89 -W 64 -o app_64bit program.c

# Architecture-specific optimization
c89 -march=native -O2 -o native_opt program.c

Warning and Error Control

# Enable all warnings
c89 -Wall -Wextra -o strict_program program.c

# Treat warnings as errors
c89 -Werror -o strict_check program.c

# Specific warning controls
c89 -Wno-unused-variable -o program program.c

Practical Examples

Development Workflow

Standard Development Build

#!/bin/bash
# Development build script for C89 compliance

# Source files
SOURCES="main.c utils.c parser.c lexer.c"
OBJECTS="main.o utils.o parser.o lexer.o"

# Compile with debugging and warnings
echo "Compiling source files..."
for src in $SOURCES; do
c89 -g -Wall -c $src
done

# Link final executable
echo "Linking executable..."
c89 -o debug_app $OBJECTS

echo "Build complete: debug_app"

Production Build Script

#!/bin/bash
# Production build with optimization

SOURCES="main.c utils.c parser.c lexer.c"
OBJECTS="main.o utils.o parser.o lexer.o"

# Clean previous builds
rm -f *.o production_app

# Compile with optimization
echo "Compiling optimized objects..."
for src in $SOURCES; do
c89 -O3 -DNDEBUG -c $src
done

# Link and strip for production
echo "Creating production executable..."
c89 -o production_app $OBJECTS
strip production_app

echo "Production build complete: production_app"

Testing Build Variants

#!/bin/bash
# Build multiple variants for testing

program="test_program"

echo "Building debug version..."
c89 -g -DDEBUG -Wall -o ${program}_debug program.c

echo "Building standard version..."
c89 -O2 -o ${program}_standard program.c

echo "Building optimized version..."
c89 -O3 -DNDEBUG -o ${program}_optimized program.c

echo "Building 32-bit version..."
c89 -W 32 -m32 -o ${program}_32bit program.c

echo "All builds complete!"

Academic and Educational Use

C89 Compliance Testing

# Strict C89 compilation (no GNU extensions)
c89 -ansi -pedantic -o strict_program program.c

# Test portability across systems
c89 -D_XOPEN_SOURCE -o portable_program program.c

# Compile with POSIX features
c89 -D_POSIX_C_SOURCE=200112L -o posix_program program.c

Student Assignment Compilation

# Compile with all warnings enabled for education
c89 -Wall -Wextra -Wshadow -Wunreachable-code \
-o assignment student_code.c

# Include debugging information for grading
c89 -g -DDEBUG_MODE -o graded_assignment student_code.c

# Check for strict C89 compliance
c89 -pedantic -std=c89 -o compliant_assignment student_code.c

System Programming

Low-Level System Programs

# Compile system utilities
c89 -O2 -D_GNU_SOURCE -o system_tool system_code.c

# Kernel module compilation (user-space part)
c89 -D_KERNEL -I/usr/src/linux/include -o kernel_interface kernel_iface.c

# System daemon compilation
c89 -O2 -s -o system_daemon daemon.c

Embedded Development

# Cross-compilation for embedded systems
c89 -march=i386 -W 32 -o embedded_app embedded_code.c

# Size-critical embedded compilation
c89 -Os -ffunction-sections -fdata-sections -o tiny_app tiny_code.c

# Real-time system compilation
c89 -O2 -DREAL_TIME -o realtime_app realtime_code.c

Integration and Automation

Build Systems

Simple Makefile for C89

# Makefile for C89 projects
CC = c89
CFLAGS = -Wall -g -O2
LDFLAGS = -lm

SOURCES = main.c utils.c parser.c
OBJECTS = $(SOURCES:.c=.o)
TARGET = myprogram

all: $(TARGET)

$(TARGET): $(OBJECTS)
$(CC) -o $@ $^ $(LDFLAGS)

%.o: %.c
$(CC) $(CFLAGS) -c $<

clean:
rm -f $(OBJECTS) $(TARGET)

debug: CFLAGS = -Wall -g -DDEBUG -O0
debug: $(TARGET)

release: CFLAGS = -Wall -O3 -DNDEBUG -s
release: $(TARGET)

Build Script with Dependencies

#!/bin/bash
# Automated build with dependency checking

PROJECT_DIR="/project/src"
BUILD_DIR="/project/build"
INCLUDE_DIR="/project/include"
LIBRARY_DIR="/project/lib"

# Create build directory
mkdir -p "$BUILD_DIR"

# Find all C source files
find "$PROJECT_DIR" -name "*.c" -print0 | while IFS= read -r -d '' source; do
# Generate object filename
object="$BUILD_DIR/$(basename "$source" .c).o"

echo "Compiling: $source -> $object"
c89 -I"$INCLUDE_DIR" -c "$source" -o "$object"

if [ $? -ne 0 ]; then
echo "Compilation failed for: $source"
exit 1
fi
done

# Link all objects
echo "Linking final executable..."
c89 -L"$LIBRARY_DIR" -o final_app "$BUILD_DIR"/*.o -lproject

echo "Build completed successfully!"

Quality Assurance

Compilation Testing Script

#!/bin/bash
# Test compilation under different conditions

source_file="program.c"
test_results="compilation_test.log"

echo "C89 Compilation Test Results" > "$test_results"
echo "=============================" >> "$test_results"

# Test 1: Basic compilation
echo "Test 1: Basic compilation" >> "$test_results"
if c89 -o test_basic "$source_file" 2>> "$test_results"; then
echo "PASS: Basic compilation successful" >> "$test_results"
else
echo "FAIL: Basic compilation failed" >> "$test_results"
fi

# Test 2: Strict C89 compliance
echo "Test 2: Strict C89 compliance" >> "$test_results"
if c89 -pedantic -ansi -o test_strict "$source_file" 2>> "$test_results"; then
echo "PASS: Strict C89 compilation successful" >> "$test_results"
else
echo "FAIL: Strict C89 compilation failed" >> "$test_results"
fi

# Test 3: Optimization
echo "Test 3: Optimization levels" >> "$test_results"
for opt in 0 1 2 3; do
if c89 -O$opt -o "test_opt$opt" "$source_file" 2>> "$test_results"; then
echo "PASS: Optimization level $opt successful" >> "$test_results"
else
echo "FAIL: Optimization level $opt failed" >> "$test_results"
fi
done

echo "Compilation tests completed. Results in: $test_results"

Code Quality Checks

#!/bin/bash
# Code quality and compliance checking

# Compile with maximum warnings
echo "Checking code quality with maximum warnings..."
c89 -Wall -Wextra -pedantic -ansi -o quality_check program.c

# Check for undefined symbols
echo "Checking for undefined symbols..."
nm -u quality_check | grep -v "^ U "

# Check for C89 compliance issues
echo "Checking C89 compliance..."
c89 -std=c89 -pedantic -fsyntax-only program.c 2>&1 | grep -i "warning\|error"

# Memory leak checking (with valgrind if available)
if command -v valgrind >/dev/null 2>&1; then
echo "Running memory leak detection..."
valgrind --leak-check=full ./quality_check
fi

Troubleshooting

Common Compilation Issues

Header File Problems

# Problem: Cannot find headers
# Solution: Specify include paths
c89 -I./include -I/usr/local/include program.c

# Problem: Conflicting headers
# Solution: Use specific include order
c89 -I./custom_include -I/usr/include program.c

# Problem: System headers not found
# Solution: Check system include paths
c89 -v program.c 2>&1 | grep "#include <...>"

Linking Errors

# Problem: Undefined references
# Solution: Add required libraries
c89 -o program program.c -lm -lpthread

# Problem: Library not found
# Solution: Specify library search path
c89 -L./lib -o program program.c -lmylib

# Problem: Multiple definitions
# Solution: Check for duplicate symbols
nm *.o | grep " T " | sort | uniq -d

Standard Compliance Issues

# Problem: Non-standard C features
# Solution: Use strict C89 mode
c89 -ansi -pedantic -o compliant_program program.c

# Problem: POSIX features needed
# Solution: Define appropriate feature test macros
c89 -D_POSIX_C_SOURCE=200112L -o posix_program program.c

# Problem: GNU extensions used
# Solution: Disable GNU extensions
c89 -std=c89 -ansi -o standard_program program.c

Performance Issues

Slow Compilation

# Problem: Slow compilation for large projects
# Solution: Use parallel compilation
make -j$(nproc)

# Solution: Precompile headers (if supported)
c89 -fpch-preprocess program.c

# Solution: Use incremental compilation
c89 -c program.c # Compile only changed files

Large Executable Size

# Problem: Executable too large
# Solution: Strip symbols
c89 -s -o small_program program.c

# Solution: Optimize for size
c89 -Os -o size_optimized program.c

# Solution: Remove unused functions
c89 -ffunction-sections -fdata-sections -Wl,--gc-segments -o stripped_program program.c
  • c99 - C99 standard C compiler
  • gcc - GNU C Compiler
  • clang - LLVM C Compiler
  • cc - Generic C compiler
  • make - Build automation tool
  • ar - Archive utility for creating static libraries
  • ld - GNU linker
  • nm - Symbol table examiner
  • objdump - Object file information utility
  • strip - Remove symbols from object files

Best Practices

  1. Always use strict C89 mode (-ansi -pedantic) for maximum portability
  2. Enable all warnings (-Wall) and treat warnings as errors in production
  3. Use appropriate optimization levels based on build type (debug vs. release)
  4. Include debugging information (-g) during development
  5. Define feature test macros (_POSIX_C_SOURCE) when using POSIX features
  6. Use consistent include and library paths across builds
  7. Test compilation on multiple platforms for portability verification
  8. Document compiler options used in project build systems
  9. Use version control for build scripts and makefiles
  10. Regularly test with -Werror to catch potential issues early

Performance Tips

  1. Use -O2 for balanced optimization between speed and compilation time
  2. Use -O3 only when necessary as it significantly increases compilation time
  3. Use -Os for size-critical applications like embedded systems
  4. Preprocess only (-E) for debugging macro expansions
  5. Compile separate translation units to enable parallel builds
  6. Use -flto for link-time optimization (if supported)
  7. Avoid excessive preprocessor definitions as they slow compilation
  8. Use profile-guided optimization for performance-critical applications
  9. Consider cross-compilation for target-specific optimizations
  10. Use static analysis tools alongside compilation for quality assurance

The c89 command provides a standardized, portable interface to C compilation that ensures strict compliance with the C89 standard. Its consistent interface across different UNIX-like systems makes it ideal for writing portable, standards-compliant C code that can be reliably compiled and executed across diverse platforms. By using c89, developers can ensure their code adheres to the well-established C89 standard, maximizing compatibility and maintainability.