summaryrefslogtreecommitdiff
path: root/zola/content
diff options
context:
space:
mode:
Diffstat (limited to 'zola/content')
-rw-r--r--zola/content/articles/safer-pointers.md6
-rw-r--r--zola/content/articles/typedef-or-not.md55
2 files changed, 54 insertions, 7 deletions
diff --git a/zola/content/articles/safer-pointers.md b/zola/content/articles/safer-pointers.md
index 1a1b55e..d6fd418 100644
--- a/zola/content/articles/safer-pointers.md
+++ b/zola/content/articles/safer-pointers.md
@@ -14,10 +14,10 @@ Tags=["C", "Patterns", "Pointers"]
Pointers are an important feature of C, but at the same time they are prone to error.
To reduce errors, and make them safer to use, I propose the following 4 tips:
-1. Encapsulating the *malloc()* and *free()* functions
+1. Encapsulating the *malloc()* and *free()* functions.
2. Using *calloc()* in the new alloc function, and making the structure "fail-safe" when everything is zero.
-3. Making the new *free* function set the freed pointer to *NULL*
-4. Every time a pointer is passed to another function, deciding who *owns* the pointer
+3. Making the new *free* function set the freed pointer to *NULL*.
+4. Every time a pointer is passed to another function, deciding who *owns* the pointer.
### Example
diff --git a/zola/content/articles/typedef-or-not.md b/zola/content/articles/typedef-or-not.md
index 9903d96..8a70f77 100644
--- a/zola/content/articles/typedef-or-not.md
+++ b/zola/content/articles/typedef-or-not.md
@@ -1,11 +1,58 @@
+++
title = "Using typedef or not"
-description = "TODO"
-date = 2024-12-20
-draft = true
+description = "When to use typedef and why"
+date = 2025-03-26
authors = ["Nicolás Dato"]
[taxonomies]
-Tags=["C"]
+Tags=["C", "Patterns"]
+++
+## General Idea
+
+Using *typedef* allows us to rename a data type, and I follow these ideas:
+- Sticking to the current coding convention.
+- Using *typedef* for encapsulated structs (i.e. hidden, opaque).
+- Using it for function pointers.
+- Avoiding it for any other case, including normal structs and enums.
+
+### Example
+
+```C
+/* The .h file */
+struct position {
+ int x;
+ int y;
+};
+
+typedef struct ctx ctx;
+
+typedef int (*context_cb)(ctx *ctx, struct position *position);
+
+ctx *new_context(context_cb cb);
+```
+
+```C
+/* The .c file */
+
+struct ctx {
+ context_cb cb;
+ /*...*/
+};
+```
+
+## Explanation
+
+I kind of avoid *typedef*, the main problem I see is that it hides the actual type.
+However, if you have an encapsulated struct then it makes sense to hide it,
+because you can't use it as a struct.
+
+I prefer to know that the type is an enum, or an struct. This way, when it is an
+struct I know that I can access its elements, and that doing it should be safe.
+If the struct is meant to be accessed only by functions, then it should be
+opaque and typedef should be used.
+
+Also, it allows you to use the same name for related things,
+like [stat](https://www.man7.org/linux/man-pages/man2/stat.2.html)
+that is a function and also the struct used in that function.
+