summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--content/projects/C_const.md107
1 files changed, 107 insertions, 0 deletions
diff --git a/content/projects/C_const.md b/content/projects/C_const.md
new file mode 100644
index 0000000..9fe86ef
--- /dev/null
+++ b/content/projects/C_const.md
@@ -0,0 +1,107 @@
++++
+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 <stddef.h>
+
+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!
+}
+```