part of c programming
.h or .c; .c is typical when it contains mainbenefits
separate-compilation model
structs
offsetof() can compute the start of a struct from a field pointer= {0} sets all fields to zerofunctions
_n-suffixed variants (e.g., list_3(2,3,4))preprocessor
#ifndef guards to allow conditional redefinition for configurationallocation pattern
terminology
parameter: variable in function declaration or definition
argument: actual value passed at call site
mmapmmap()
used internally by malloc on linux as a low-level allocator
maps files into virtual memory pages
page faults occur when accessing unloaded regions
example
file_buffer = mmap(0, file_size, PROT_READ, MAP_SHARED, fd, 0); md5((unsigned char*)file_buffer, file_size, result); munmap(file_buffer, file_size);
here are some alternative type names that could be used:
i8 i16 i32 i64 i8_least i16_least i32_least i64_least i8_fast i16_fast i32_fast i64_fast u8 u16 u32 u64 u8 u16_least u32_least u64_least u8_fast u16_fast u32_fast u64_fast f32 float f64 double pointer boolean
incidentally, makers of the rust language had the same idea and are using some of these type names
flat arrays use one contiguous block
i = d1*(d2*d3)+d2*d3+d3nested arrays
each subarray separately allocated
simpler indexing and iteration
requires multiple allocations and frees
pros
cons
adds struct setup overhead
limits pointer arithmetic flexibility
shared size across arrays requires extra handling
not always useful if function already accepts a count argument
resizing policies
cons
reallocation requires pointer updates
operations can fail on allocation
alignment rules
examples
small before large adds padding
order members from largest to smallest to reduce padding
arrays follow base-type alignment
struct size padded to largest-member alignment
greater type specificity
verbosity
more declarations and boilerplate
fine-grained control often offsets the cost in clarity and performance
header-only inclusion
header plus shared library
separate header and c file inclusion
single translation unit
.c files included into one top-level .c for compact projectsrepeated inclusion under different macros
resize pattern
n as argumentif current capacity is smaller, grow by either
n - available, orensure pattern
ensures allocation of at least n elements
allocates new storage if pointer is null
check input before calling ensure to decide if additional initialization on new allocation is needed
goals
stdio.h printf is fickle when it comes to matching format tags with arguments. it uses c standard variadic arguments, which have it read arguments based on the format tag associated size from an argument bytestream.
if the format tag is not matching the type, the printing will be corrupted.
printf does not have string type tags for fixed length types from inttypes.h. macros are the only solution currently
printf("64 bit %" PRIu64 " printed here\n" u64variable);
a more robust printf might: