What is the complete usage of predefined macros and conditional compilation in C language?
Predefined Macros:
-
Standard Predefined Macros
cvoid print_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__); #ifdef __STDC_VERSION__ printf("C Standard: %ld\n", __STDC_VERSION__); #endif } -
Compiler-Specific Macros
cvoid compiler_specific_code() { #ifdef __GNUC__ printf("GCC compiler\n"); #elif defined(__clang__) printf("Clang compiler\n"); #elif defined(_MSC_VER) printf("MSVC compiler\n"); #endif } -
Platform Detection
cvoid platform_specific_code() { #ifdef _WIN32 printf("Windows platform\n"); #elif defined(__linux__) printf("Linux platform\n"); #elif defined(__APPLE__) printf("macOS platform\n"); #endif }
Conditional Compilation:
-
Basic Conditional Compilation
c#ifdef DEBUG #define LOG(x) printf x #else #define LOG(x) #endif void function() { LOG(("Debug message\n")); } -
Multiple Conditions
c#if defined(UNIX) && !defined(DEBUG) #define OPTIMIZED_CODE #endif #if VERSION >= 2 #include "new_features.h" #else #include "legacy_features.h" #endif -
Errors and Warnings
c#if SIZE < 0 #error "Size must be positive" #endif #if !defined(VERSION) #warning "VERSION not defined, using default" #define VERSION "1.0" #endif
Advanced Usage:
-
Macro Stringification
c#define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) printf("Line: %s\n", TOSTRING(__LINE__)); -
Macro Concatenation
c#define CONCAT(a, b) a##b int CONCAT(var, 1) = 10; // var1 -
Variadic Macros
c#define LOG(fmt, ...) printf("[LOG] " fmt "\n", ##__VA_ARGS__) LOG("Value: %d", 42); LOG("Simple message");
Practical Applications:
-
Debug Macros
c#ifdef DEBUG #define DEBUG_PRINT(fmt, ...) \ printf("[DEBUG %s:%d] " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__) #else #define DEBUG_PRINT(fmt, ...) #endif void example_function() { DEBUG_PRINT("Processing data: %d", 100); } -
Version Control
c#define VERSION_MAJOR 2 #define VERSION_MINOR 5 #define VERSION_PATCH 1 #define VERSION_STRING \ TOSTRING(VERSION_MAJOR) "." \ TOSTRING(VERSION_MINOR) "." \ TOSTRING(VERSION_PATCH) printf("Version: %s\n", VERSION_STRING); -
Cross-Platform Code
c#ifdef _WIN32 #define PATH_SEPARATOR '\\' #define PATH_SEPARATOR_STR "\\" #else #define PATH_SEPARATOR '/' #define PATH_SEPARATOR_STR "/" #endif void join_path(char *dest, const char *dir, const char *file) { sprintf(dest, "%s%s%s", dir, PATH_SEPARATOR_STR, file); } -
Feature Toggles
c#define FEATURE_A_ENABLED 1 #define FEATURE_B_ENABLED 0 void process_data() { #if FEATURE_A_ENABLED feature_a_process(); #endif #if FEATURE_B_ENABLED feature_b_process(); #endif }
Best Practices:
-
Header Guards
c#ifndef HEADER_H #define HEADER_H // Header content #endif -
Include Once
c#pragma once // Header content -
Macro Scope Control
c#undef TEMP_MACRO #define TEMP_MACRO(x) (x * 2) int result = TEMP_MACRO(5); #undef TEMP_MACRO
Important Considerations:
-
Macro Side Effects
c#define SQUARE(x) ((x) * (x)) int i = 2; int result = SQUARE(i++); // Undefined behavior -
Macro Parentheses
c#define MUL(a, b) ((a) * (b)) int result = MUL(2 + 3, 4); // Correct: (2 + 3) * 4 = 20 -
Nested Conditional Compilation
c#ifdef DEBUG #ifdef VERBOSE #define LOG(x) printf x #else #define LOG(x) #endif #else #define LOG(x) #endif