c
examples
examples.c🔧c
/*
* ============================================================================
* COMPILATION PROCESS - EXAMPLES
* ============================================================================
* This file demonstrates the different stages of C compilation.
*
* To see each stage:
*
* Stage 1 - Preprocessing: gcc -E examples.c -o examples.i
* Stage 2 - Compilation: gcc -S examples.c -o examples.s
* Stage 3 - Assembly: gcc -c examples.c -o examples.o
* Stage 4 - Linking: gcc examples.o -o examples
*
* Or all at once: gcc examples.c -o examples
*
* Run: ./examples
* ============================================================================
*/
/* ============================================================================
* STAGE 1: PREPROCESSOR EXAMPLES
* ============================================================================
* These directives are processed BEFORE compilation.
* The preprocessor does text substitution and file inclusion.
*/
// File inclusion - the contents of stdio.h are inserted here
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Simple constant definition
#define PI 3.14159265359
#define E 2.71828182846
// Macro with parameters (like inline functions)
#define SQUARE(x) ((x) * (x))
#define CUBE(x) ((x) * (x) * (x))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
// String concatenation macro
#define STR(x) #x
#define CONCAT(a, b) a##b
// Conditional compilation
#define DEBUG_MODE 1
#define VERSION 2
// Feature flags
#define FEATURE_LOGGING 1
#define FEATURE_METRICS 0
/* ============================================================================
* DEMONSTRATION FUNCTIONS
* ============================================================================
*/
/*
* Example 1: Macro Expansion
* --------------------------
* Shows how #define macros are replaced during preprocessing.
* Run: gcc -E examples.c | grep -A5 "example_macro_expansion"
*/
void example_macro_expansion() {
printf("\n=== Example 1: Macro Expansion ===\n");
// These constants are replaced by their values during preprocessing
printf("PI = %.10f\n", PI);
printf("E = %.10f\n", E);
// Macro functions are expanded inline
int x = 5;
printf("\nx = %d\n", x);
printf("SQUARE(%d) = %d\n", x, SQUARE(x));
printf("CUBE(%d) = %d\n", x, CUBE(x));
// What the preprocessor sees after expansion:
// SQUARE(5) becomes ((5) * (5)) = 25
// CUBE(5) becomes ((5) * (5) * (5)) = 125
int a = 10, b = 20;
printf("\na = %d, b = %d\n", a, b);
printf("MAX(%d, %d) = %d\n", a, b, MAX(a, b));
printf("MIN(%d, %d) = %d\n", a, b, MIN(a, b));
}
/*
* Example 2: Stringification and Token Pasting
* --------------------------------------------
* Special preprocessor operators # and ##
*/
void example_stringification() {
printf("\n=== Example 2: Stringification ===\n");
// # operator converts argument to string
printf("STR(Hello) = %s\n", STR(Hello));
printf("STR(123) = %s\n", STR(123));
// ## operator concatenates tokens
int CONCAT(var, 1) = 100; // Creates variable var1
int CONCAT(var, 2) = 200; // Creates variable var2
printf("var1 = %d\n", var1);
printf("var2 = %d\n", var2);
}
/*
* Example 3: Conditional Compilation
* ----------------------------------
* Code is included or excluded based on conditions.
*/
void example_conditional_compilation() {
printf("\n=== Example 3: Conditional Compilation ===\n");
// #ifdef - if defined
#ifdef DEBUG_MODE
printf("DEBUG_MODE is defined\n");
printf("Debug: This message only appears in debug builds\n");
#else
printf("DEBUG_MODE is NOT defined\n");
#endif
// #if with expressions
#if VERSION == 1
printf("Version 1 code\n");
#elif VERSION == 2
printf("Version 2 code\n");
#else
printf("Unknown version\n");
#endif
// Feature flags
#if FEATURE_LOGGING
printf("Logging feature is enabled\n");
#endif
#if FEATURE_METRICS
printf("Metrics feature is enabled\n");
#else
printf("Metrics feature is disabled\n");
#endif
// Platform detection
#ifdef _WIN32
printf("Platform: Windows\n");
#elif defined(__linux__)
printf("Platform: Linux\n");
#elif defined(__APPLE__)
printf("Platform: macOS\n");
#else
printf("Platform: Unknown\n");
#endif
}
/*
* Example 4: Predefined Macros
* ----------------------------
* Compiler provides these automatically.
*/
void example_predefined_macros() {
printf("\n=== Example 4: Predefined Macros ===\n");
// Standard predefined macros
printf("File: %s\n", __FILE__);
printf("Line: %d\n", __LINE__);
printf("Date: %s\n", __DATE__);
printf("Time: %s\n", __TIME__);
printf("Function: %s\n", __func__); // C99
// Compiler version (GCC specific)
#ifdef __GNUC__
printf("GCC Version: %d.%d.%d\n",
__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
#endif
// C standard version
#if defined(__STDC_VERSION__)
printf("C Standard: %ld\n", __STDC_VERSION__);
#endif
}
/*
* Example 5: Include Guards
* -------------------------
* Prevents multiple inclusion of header files.
*/
// Simulating a header file with include guards
#ifndef MY_HEADER_H
#define MY_HEADER_H
// This content only appears once, even if included multiple times
struct MyStruct {
int value;
};
#endif // MY_HEADER_H
// Modern alternative using #pragma once (compiler-specific)
// #pragma once
void example_include_guards() {
printf("\n=== Example 5: Include Guards ===\n");
printf("Include guards prevent multiple definitions.\n");
printf("Pattern:\n");
printf(" #ifndef HEADER_H\n");
printf(" #define HEADER_H\n");
printf(" // ... header content ...\n");
printf(" #endif\n");
struct MyStruct s;
s.value = 42;
printf("MyStruct.value = %d\n", s.value);
}
/* ============================================================================
* STAGE 2: COMPILER OUTPUT DEMONSTRATION
* ============================================================================
* These functions show code that will be converted to assembly.
* Run: gcc -S examples.c -o examples.s && cat examples.s
*/
/*
* Example 6: Simple Function for Assembly Analysis
* ------------------------------------------------
* A simple function to see the assembly output.
*/
int add_numbers(int a, int b) {
return a + b;
}
int multiply_numbers(int a, int b) {
return a * b;
}
void example_assembly_output() {
printf("\n=== Example 6: Assembly Output ===\n");
int x = 10, y = 20;
int sum = add_numbers(x, y);
int product = multiply_numbers(x, y);
printf("%d + %d = %d\n", x, y, sum);
printf("%d * %d = %d\n", x, y, product);
printf("\nTo see assembly:\n");
printf(" gcc -S examples.c -o examples.s\n");
printf(" cat examples.s | grep -A20 \"add_numbers\"\n");
}
/*
* Example 7: Optimization Levels
* ------------------------------
* Different optimization levels produce different code.
*/
void example_optimization() {
printf("\n=== Example 7: Optimization Levels ===\n");
// This loop can be optimized by the compiler
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
printf("Sum of 1 to 100: %d\n", sum);
// Constant folding example
int result = 2 + 3; // Compiler may compute this at compile time
printf("2 + 3 = %d\n", result);
// Dead code elimination
int unused = 42; // May be eliminated with optimization
(void)unused; // Suppress warning
printf("\nOptimization flags:\n");
printf(" -O0 : No optimization (default)\n");
printf(" -O1 : Basic optimization\n");
printf(" -O2 : Standard optimization\n");
printf(" -O3 : Maximum optimization\n");
printf(" -Os : Optimize for size\n");
}
/* ============================================================================
* STAGE 3 & 4: OBJECT FILES AND LINKING
* ============================================================================
*/
// External function declaration (would be in another file normally)
// extern int external_function(int x);
/*
* Example 8: Symbol Table
* -----------------------
* Shows how functions become symbols in object files.
*/
// This function will appear in the symbol table as "public_function"
int public_function(int x) {
return x * 2;
}
// Static functions are local to this file
static int private_function(int x) {
return x * 3;
}
void example_symbol_table() {
printf("\n=== Example 8: Symbol Table ===\n");
printf("public_function(5) = %d\n", public_function(5));
printf("private_function(5) = %d\n", private_function(5));
printf("\nTo see symbols:\n");
printf(" gcc -c examples.c -o examples.o\n");
printf(" nm examples.o\n");
printf("\n");
printf("Symbol types:\n");
printf(" T - Text (code) section, global\n");
printf(" t - Text section, local (static)\n");
printf(" U - Undefined (external reference)\n");
printf(" D - Initialized data\n");
printf(" B - Uninitialized data (BSS)\n");
}
/*
* Example 9: External References
* ------------------------------
* Shows how linking resolves external references.
*/
void example_external_references() {
printf("\n=== Example 9: External References ===\n");
// printf is an external reference - defined in libc
printf("printf is defined in libc\n");
// malloc is another external reference
int *ptr = malloc(sizeof(int));
if (ptr) {
*ptr = 100;
printf("malloc allocated memory at: %p\n", (void*)ptr);
free(ptr); // free is also from libc
}
// strlen is from string.h (libc)
printf("strlen(\"Hello\") = %lu\n", strlen("Hello"));
printf("\nTo see shared libraries:\n");
printf(" gcc examples.c -o examples\n");
printf(" ldd examples\n");
}
/*
* Example 10: Complete Compilation Steps
* --------------------------------------
* Demonstrates all stages together.
*/
void example_complete_compilation() {
printf("\n=== Example 10: Complete Compilation Steps ===\n");
printf("\nFour stages of compilation:\n\n");
printf("1. PREPROCESSING (gcc -E source.c -o source.i)\n");
printf(" - Expands #include directives\n");
printf(" - Replaces #define macros\n");
printf(" - Removes comments\n");
printf(" - Handles conditional compilation\n");
printf("\n");
printf("2. COMPILATION (gcc -S source.c -o source.s)\n");
printf(" - Lexical analysis (tokenization)\n");
printf(" - Syntax analysis (parsing)\n");
printf(" - Semantic analysis\n");
printf(" - Generates assembly code\n");
printf("\n");
printf("3. ASSEMBLY (gcc -c source.c -o source.o)\n");
printf(" - Converts assembly to machine code\n");
printf(" - Creates object file with symbol table\n");
printf("\n");
printf("4. LINKING (gcc source.o -o executable)\n");
printf(" - Resolves external references\n");
printf(" - Links with libraries\n");
printf(" - Creates final executable\n");
printf("\n");
printf("Quick compilation: gcc source.c -o program\n");
printf("Run the program: ./program\n");
}
/*
* Main Function - Entry Point
*/
int main() {
printf("╔════════════════════════════════════════════════╗\n");
printf("║ COMPILATION PROCESS EXAMPLES ║\n");
printf("║ Understanding how C code becomes executable ║\n");
printf("╚════════════════════════════════════════════════╝\n");
// Run all examples
example_macro_expansion();
example_stringification();
example_conditional_compilation();
example_predefined_macros();
example_include_guards();
example_assembly_output();
example_optimization();
example_symbol_table();
example_external_references();
example_complete_compilation();
printf("\n=== All Examples Completed! ===\n");
printf("\nTry the compilation commands shown in each example.\n");
return 0;
}