# C volatile qualifier **C volatile qualifier** tells the compiler to never optimize away memory accesses. Declare as `volatile int x` to prevent caching in registers. Used for hardware registers, shared memory, signal handlers, or any data that can change outside program control. Use volatile for hardware-mapped memory, global state accessed by signal handlers, or data shared with other code. ## Example ```c // compile: gcc -o volatile volatile.c // run: ./volatile // description: volatile for hardware and signal access #include #include #include volatile sig_atomic_t flag = 0; void signal_handler(int sig) { flag = 1; } // Hardware register (simulated) volatile int *hardware_reg = (volatile int *)0x12345678; int main() { signal(SIGUSR1, signal_handler); printf("Waiting for signal (send SIGUSR1 to PID %d)\n", getpid()); // Without volatile: compiler might cache flag in register // With volatile: every access reads from memory int iterations = 0; while (!flag && iterations < 1000000) { iterations++; } if (flag) { printf("Signal received after %d iterations\n", iterations); } else { printf("No signal (timeout)\n"); } return 0; } ``` ## Common patterns **When to use volatile**: - Hardware registers (memory-mapped I/O) - Shared memory with other processes/threads - Signal handler variables (use `sig_atomic_t`) - Variables modified by external code **Semantics**: - Compiler reads/writes every access (no caching) - No optimization across volatile accesses - Guarantees ordering with respect to volatile **Not a substitute for**: - Locks (doesn't prevent race conditions) - Atomic operations (not atomic) - Synchronization (use mutexes, atomics) **Signal handlers**: - Only `volatile sig_atomic_t` is safe in handlers - Even `volatile int` not sufficient for signals - `sig_atomic_t` guaranteed atomic signal-safe access **Optimization prevention**: - Compiler assumes non-volatile can be cached - Volatile forces memory access each time - Performance cost: prevents useful optimizations **Modern alternatives**: - `_Atomic` (C11) for thread-safe atomics - `volatile _Atomic` for signal handlers + threading - Mutexes for shared memory (C threads)