Docs

Comments and Documentation

Comments and Documentation in C

📖 Introduction

Comments are explanatory text that the compiler ignores. They help make code understandable for humans - including your future self! Good documentation is a hallmark of professional code.


🎯 Types of Comments

                      C Comments
                          │
            ┌─────────────┴─────────────┐
            │                           │
     Single-Line                   Multi-Line
       // ...                      /* ... */
            │                           │
   C99 and later                 C89 compatible
   One line only                 Can span lines

📝 Single-Line Comments (//)

Single-line comments start with // and continue to the end of the line.

// This is a single-line comment

int count = 10;  // Initialize counter

// You can have multiple
// single-line comments
// in a row

Characteristics:

  • Available since C99 (borrowed from C++)
  • Cannot span multiple lines
  • Often used for brief explanations

📋 Multi-Line Comments (/* */)

Multi-line comments start with /* and end with */.

/* This is a multi-line comment.
   It can span multiple lines.
   Very useful for longer explanations. */

/*
 * This is a more stylized
 * multi-line comment with
 * asterisks on each line.
 */

int x = 5; /* inline comment */ int y = 10;

Characteristics:

  • Available since C89 (original C)
  • Can span multiple lines
  • Can appear anywhere in code
  • Cannot be nested!

⚠️ Nesting Problem:

/* Outer comment
   /* Inner comment */  <- This ends the outer comment!
   More text here causes an error
*/  // ERROR: This is now outside the comment

🏗️ Documentation Comments

Function Documentation:

/**
 * @brief Calculates the factorial of a number.
 *
 * This function computes n! (n factorial) using
 * an iterative approach. For n = 0, returns 1.
 *
 * @param n The non-negative integer to compute factorial for
 * @return The factorial of n, or -1 if n is negative
 *
 * @warning For n > 12, result may overflow 32-bit int
 * @see power(), fibonacci()
 *
 * @example
 *     int result = factorial(5);  // result = 120
 */
int factorial(int n) {
    if (n < 0) return -1;
    if (n == 0) return 1;

    int result = 1;
    for (int i = 2; i <= n; i++) {
        result *= i;
    }
    return result;
}

Common Documentation Tags:

TagDescription
@briefShort description
@paramParameter description
@returnReturn value description
@warningWarning about usage
@noteAdditional notes
@seeReference to related items
@exampleUsage example
@authorAuthor information
@dateDate created/modified
@versionVersion number
@deprecatedMarks as deprecated
@todoPending tasks

📄 File Header Comments

Every source file should start with a header comment:

/**
 * @file calculator.c
 * @brief Simple calculator implementation
 *
 * This file contains functions for basic arithmetic
 * operations including addition, subtraction,
 * multiplication, and division.
 *
 * @author John Smith
 * @date 2024-01-15
 * @version 1.0
 *
 * @copyright Copyright (c) 2024 Example Corp
 * @license MIT License
 *
 * Revision History:
 *   1.0 - Initial release
 *   1.1 - Added error handling for division by zero
 */

#include <stdio.h>
#include <stdlib.h>

// Rest of the code...

🔧 Function Header Comments

/**
 * @brief Searches for a value in a sorted array using binary search.
 *
 * @param arr     Pointer to the sorted array (must be ascending order)
 * @param size    Number of elements in the array
 * @param target  Value to search for
 *
 * @return Index of target if found, -1 otherwise
 *
 * @pre arr must not be NULL
 * @pre arr must be sorted in ascending order
 * @pre size must be > 0
 *
 * @post Array is unchanged
 *
 * @note Time complexity: O(log n)
 * @note Space complexity: O(1)
 *
 * @example
 *     int arr[] = {1, 3, 5, 7, 9};
 *     int idx = binarySearch(arr, 5, 7);  // idx = 3
 */
int binarySearch(int *arr, int size, int target) {
    int left = 0;
    int right = size - 1;

    while (left <= right) {
        int mid = left + (right - left) / 2;

        if (arr[mid] == target) {
            return mid;
        } else if (arr[mid] < target) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }

    return -1;  // Not found
}

📐 Inline Comments

Good Inline Comments:

// Calculate the area of a circle: A = πr²
float area = 3.14159f * radius * radius;

// Handle the edge case where divisor is zero
if (divisor == 0) {
    return ERROR_DIVIDE_BY_ZERO;
}

// Use bitwise AND to check if number is odd
// (odd numbers have LSB = 1)
if (n & 1) {
    printf("Odd number\n");
}

Bad Inline Comments:

// BAD: States the obvious
int x = 5;  // Set x to 5

// BAD: Doesn't explain WHY
count++;  // Increment count

// BAD: Outdated comment (code says otherwise)
// Add 10 to the value
value = value - 10;

🏷️ Section Comments

Divide your code into logical sections:

/* ============================================================
 * INCLUDES AND DEFINITIONS
 * ============================================================ */
#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 100

/* ============================================================
 * TYPE DEFINITIONS
 * ============================================================ */
typedef struct {
    int x, y;
} Point;

/* ============================================================
 * GLOBAL VARIABLES
 * ============================================================ */
static int globalCounter = 0;

/* ============================================================
 * HELPER FUNCTIONS
 * ============================================================ */
static int helper(int n) {
    return n * 2;
}

/* ============================================================
 * PUBLIC FUNCTIONS
 * ============================================================ */
int publicFunction(int n) {
    return helper(n) + 1;
}

/* ============================================================
 * MAIN FUNCTION
 * ============================================================ */
int main() {
    // ...
}

🔄 TODO and FIXME Comments

Mark work in progress:

// TODO: Add error handling for null pointer
void processData(int *data) {
    // ...
}

// FIXME: This causes memory leak when buffer is full
char* readFile(const char* filename) {
    // ...
}

// HACK: Temporary workaround for bug #123
// Remove after library update
data[0] = data[0] & 0xFF;

// NOTE: This assumes little-endian architecture
int value = *(int*)buffer;

// XXX: Potential security vulnerability - review
strcpy(dest, src);

Common Markers:

MarkerPurpose
TODOFeature to add
FIXMEBug to fix
HACKTemporary workaround
NOTEImportant information
XXXNeeds attention
BUGKnown bug
OPTIMIZEOptimization opportunity

📊 Documenting Data Structures

/**
 * @struct Student
 * @brief Represents a student record in the system.
 *
 * Contains personal information and academic data
 * for a single student enrolled in the institution.
 */
typedef struct {
    char name[50];      /**< Full legal name of student */
    int id;             /**< Unique 6-digit student ID */
    float gpa;          /**< Current GPA (0.0 to 4.0) */
    int credits;        /**< Total credit hours completed */
    int isActive;       /**< 1 if currently enrolled, 0 otherwise */
} Student;

/**
 * @enum ErrorCode
 * @brief Return codes for library functions.
 */
typedef enum {
    SUCCESS = 0,           /**< Operation completed successfully */
    ERROR_NULL_POINTER,    /**< NULL pointer passed as argument */
    ERROR_OUT_OF_MEMORY,   /**< Memory allocation failed */
    ERROR_INVALID_INPUT,   /**< Input validation failed */
    ERROR_FILE_NOT_FOUND   /**< Specified file does not exist */
} ErrorCode;

/**
 * @def MAX_STUDENTS
 * @brief Maximum number of students the system can handle.
 *
 * This limit is based on available memory and database
 * constraints. Increase with caution.
 */
#define MAX_STUDENTS 1000

⚙️ Conditional Compilation Comments

#ifdef DEBUG
    // This code only runs in debug builds
    printf("Debug: x = %d\n", x);
#endif

#if 0
    // This code is "commented out" using preprocessor
    // Useful for large blocks of code
    printf("This will never run\n");
    int unused = 42;
#endif

/* Commented out - keeping for reference
void oldFunction() {
    // Old implementation
}
*/

📏 Comment Style Guidelines

Do's:

  1. Explain WHY, not WHAT

    // Bad: Increment counter
    // Good: Increment counter to skip the header row
    counter++;
    
  2. Keep comments updated with code

  3. Comment complex algorithms

    // Using Euclidean algorithm to find GCD:
    // gcd(a, b) = gcd(b, a % b) until b = 0
    while (b != 0) {
        int temp = b;
        b = a % b;
        a = temp;
    }
    
  4. Document function contracts

  5. Use consistent style throughout project

Don'ts:

  1. Don't state the obvious

    // Bad
    i++;  // Add 1 to i
    
  2. Don't leave commented-out code (use version control)

  3. Don't write misleading comments

  4. Don't over-comment

  5. Don't use comments to excuse bad code

    // Bad
    int a;  // This is the number of apples
    
    // Good
    int numberOfApples;  // Self-documenting
    

🛠️ Documentation Tools

Doxygen:

Generate documentation from comments:

/**
 * @mainpage My Project Documentation
 *
 * @section intro Introduction
 * This is my awesome C project...
 *
 * @section install Installation
 * Follow these steps...
 */

Run: doxygen Doxyfile

Example Doxyfile Configuration:

PROJECT_NAME = "My C Project"
OUTPUT_DIRECTORY = ./docs
INPUT = ./src
RECURSIVE = YES
GENERATE_HTML = YES
GENERATE_LATEX = NO

✅ Best Practices Summary

  1. Header comments for every file
  2. Function documentation for all public functions
  3. Inline comments for complex or non-obvious code
  4. Use consistent style throughout the project
  5. Keep comments updated when code changes
  6. Prefer self-documenting code with clear names
  7. Document assumptions and constraints
  8. Use TODO/FIXME markers for pending work
  9. Don't over-comment obvious code
  10. Review comments during code review

🔑 Key Takeaways

  1. Single-line // comments for brief notes (C99+)
  2. Multi-line /* */ comments for longer explanations
  3. Document WHY, not just WHAT
  4. Use documentation tags (@param, @return, etc.)
  5. Keep comments synchronized with code
  6. Self-documenting code reduces need for comments
  7. Use section dividers in larger files
  8. Consider using documentation generators like Doxygen

⏭️ Next Module

Continue to Module 3: Control Structures to learn about decision making and loops.

Comments And Documentation - C Programming Tutorial | DeepML