+++ title = "C: the const modifier" date = 2024-08-23 [extra] latex = true +++ --- ### The `C` `const` modifier with nested pointers The `const` is a way to tell the `C` compiler to consider the target variable read-only. On function declaration, the data arguments are _de facto_ `const`, but we could specify the pointers' behavior as seen below. _The key is to apply the `const` modifier from right to left_ ```C /* August 2024, C99. * Const modifier to data pointers. * Note: the patterns are just layers of Pascal's binomial triangle, * easy to repete for a growing number of stars. */ /* * Zero star. */ /* Zero const modifier -> 1 choose 0. */ static int data; /* One const modifier -> 1 choose 1. */ static int const constData; /* * One star */ /* Zero const modifier -> 2 choose 0. */ static int *ptr_data; /* One const modifier -> 2 choose 1. */ static int const *ptr_constData; static int *const constPtr_data; /* Two const modifiers -> 2 choose 2. */ static int const *const constPtr_constData; /* * Two stars */ /* Zero const modifier -> 3 choose 0. */ static int **ptr_ptr_data; /* One const modifier -> 3 choose 1. */ static int const **ptr_ptr_constData; static int *const *ptr_constPtr_Data; static int **const constPtr_ptr_Data; /* Two const modifiers -> 3 choose 2. */ static int const *const *ptr_constPtr_constData; static int const **const constPtr_ptr_constData; static int *const *const constPtr_constPtr_data; /* Three const modifiers -> 3 choose 3. */ static int const *const *const constPtr_constPtr_constData; /* * Three stars */ /* Zero const modifier -> 4 choose 0. */ static int ***ptr_ptr_ptr_data; /* One const modifier -> 4 choose 1. */ static int const ***ptr_ptr_ptr_constData; static int *const **ptr_ptr_constPtr_data; static int **const *ptr_constPtr_ptr_data; static int ***const constPtr_ptr_ptr_data; /* Two const modifiers -> 4 choose 2. */ static int const *const **ptr_ptr_constPtr_constData; static int const **const *ptr_constPtr_ptr_constData; static int const ***const constPtr_ptr_ptr_constData; static int *const *const *ptr_constPtr_constPtr_data; static int *const **const constPtr_ptr_constPtr_data; static int **const *const constPtr_constPtr_ptr_data; /* Three const modifiers -> 4 choose 3. */ static int const *const *const *ptr_constPtr_constPtr_constData; static int const *const **const constPtr_ptr_constPtr_constData; static int const **const *const constPtr_constPtr_ptr_constData; static int *const *const *const constPtr_constPtr_constPtr_data; /* Four const modifiers -> 4 choose 4. */ static int const *const *const *const constPtr_constPtr_constPtr_constData; ``` We can then do the same for following stars depth, but as we can see the number of possibilities is combinatorial: for \\(n\\) stars-pointers we will have \\(2^{n + 1}\\) `const` flavours possible. You can verify the above assumptions by: ```C #include void foo(int *ptr_data, int const *ptr_constData, int *const constPtr_data, int const *const constPtr_constData) { *ptr_data = 0; // OK: modifies the pointed data ptr_data = NULL; // OK: modifies the pointer *ptr_constData = 0; // Error! ptr_constData = NULL; // OK: modifies the pointer *constPtr_data = 0; // OK: modifies the pointed data constPtr_data = NULL; // Error! *constPtr_constData = 0; // Error! constPtr_constData = NULL; // Error! } ```