Lecture 019

The C Pre-processor Language

C program has statements written: - C preprocessor language - C proper

Compiling Process

Compiling Process

Header File Inclusion

#include <stdio.h> // for io
#include <stdbool.h> // for boolean
#include "lib/xalloc.h"
// you can include other things, but not a good idea (never include a .c file)
// notice that inclution have different symbol

header file:

Macro Definition

#define INT_MIN 0x80000000
// preprocessor replaces INT_MIN with 0x80000000
// compiler never sees INT_MIN

#define INT_MAX INT_MIN^-1
// then when you write INT_MAX / 2
// it will replace string as 0x80000000^-1/2
// which C understand as 0x80000000^(-1/2)
#define INT_MAX (INT_MIN^-1)
// this is better

#define MULT(x, y)((x)*(y))
// you can also define function
// observe how many prentheses you need

Compiling Macro

Compiling Macro

Macro, Symbol, Definition

Macro, Symbol, Definition

Conditional Compilation

Compile based on whether a variable is defined

#ifdef DEBUG
  printf("Reached this point\n")

// use else
#ifdef X86_ARCH
  #include "arch/x86_optimizations.h"

// we can also check if not defined
#ifndef INT_MIN
  #define INT_MIN 0x80000000

Contracts Emulation

C has no contracts contracts.h:



Translation Example




int32_t: %d, %i

printf("%d", 50);            // Prints 50
printf("%d", -213);          // Prints -213
printf("%i", -213);          // Prints -213
int64_t x = 4294967296;      // 4,294,967,296 is 2^32
unsigned int y = 4294967295; // 4,294,967,295 is 2^32 - 1
printf("%d and %d", x, y);   // Prints 0 and -1

uint32_t: %u

printf("%u", 500);       // Prints 500
printf("%u", -500);      // Prints 4294966796
uint64_t x = 4294967296; // 4,294,967,296 is 2^32
printf("%u", x);         // Prints 0

uint32_t: %x, %X

printf("%x", 31);    // Prints 1f
printf("%X", 31);    // Prints 1F
printf("%X", -2);    // Prints FFFFFFFE
long a = 4294967296; // 4,294,967,296 is 2^32
printf("%x", a);     // Prints 0

Unsigned Octal Integer

printf("%o", 31);    // Prints 37
printf("%o", -2);    // Prints 37777777776
long a = 4294967296; // 4,294,967,296 is 2^32
printf("%o", a);     // Prints 0

More on Printing: Here

Compiling a C Program



C compiles separately

C compiles separately

Using valgrind

Using valgrind
More on Valgrind: Here

Memory and Garbage Collection

When Allocation

  1. allocate the size of bytes
  2. using xmalloc or xcalloc instead
  3. clean the memory allocated

Garbage Collection

Without Garbage Collection, memory will only un-allocate upon program exit.

Freeing Data Structure:

Example: Freeing a Tree

Example: Freeing a Tree

Lost Gained
contracts preprocessor
safety whimsical execution
garbege collection explicit memory management
memory initialization separate compilation

String in C: https://www.youtube.com/watch?v=90gFFdzuZMw&ab_channel=EngineerMan You should not free the function by passing free(fn_pointer) because functions are not in heap Array Pointer: https://www.youtube.com/watch?v=y2BAaD3fW8A&ab_channel=LuisCeze

Table of Content