doc: Add talloc tutorial.
[Samba/vl.git] / lib / talloc / doc / tutorial_dts.dox
blob9065d7a1f0c3421ebaf50dec2dcccb0a028068b6
1 /**
2 @page libtalloc_dts Chapter 3: Dynamic type system
3 @section dts Dynamic type system
5 Generic programming in the C language is very difficult. There is no inheritance
6 nor templates known from object oriented languages. There is no dynamic type
7 system. Therefore, generic programming in this language is usually done by
8 type-casting a variable to |void*| and transferring it through a generic function
9 to a specialized callback as illustrated on the next listing.
11 @code
12 void generic_function(callback_fn cb, void *pvt)
14   /* do some stuff and call the callback */
15   cb(pvt);
18 void specific_callback(void *pvt)
20   struct specific_struct *data;
21   data = (struct specific_struct*)pvt;
22   /* ... */
25 void specific_function()
27   struct specific_struct data;
28   generic_function(callback, &data);
30 @endcode
32 Unfortunately, the type information is lost as a result of this type cast. The
33 compiler cannot check the type during the compilation nor are we able to do it
34 at runtime. Providing an invalid data type to the callback will result
35 in unexpected behaviour (not necessarily a crash) of the application. This
36 mistake is usually hard to detect because it is not the first thing on the mind
37 of the developer.
39 As we already know, every talloc context contains a name. This name is available
40 at any time and it can be used to determine the type of a context even if we
41 lose the type of a variable.
43 Although the name of the context can be set to any arbitrary string, the best
44 way of using it to simulate the dynamic type system is to set it directly to the
45 type of the variable.
47 It is recommended to use one of |talloc()| and |talloc_array()| (or its
48 variants) to create the context as they set its name to the name of the type
49 automatically.
51 If we have a context with such a name, we can use two similar functions that do
52 both the type check and the type cast for us:
54 - talloc_get_type()
55 - talloc_get_type_abort()
57 @section dts-examples Examples
59 Below given is an example of generic programming with talloc - if we provide
60 invalid data to the callback, the program will be aborted. This is a sufficient
61 reaction for such an error in most applications.
63 @code
64 void foo_callback(void *pvt)
66   struct foo *data = talloc_get_type_abort(pvt, struct foo);
67   /* ... */
70 int do_foo()
72   struct foo *data = talloc_zero(NULL, struct foo);
73   /* ... */
74   return generic_function(foo_callback, data);
76 @endcode
78 But what if we are creating a service application that should be running for the
79 uptime of a server? We may want to abort the application during the development
80 process (to make sure the error is not overlooked) but try to recover from the
81 error in the customer release. This can be achieved by creating a custom abort
82 function with a conditional build.
84 @code
85 void my_abort(const char *reason)
87   fprintf(stderr, "talloc abort: %s\n", reason);
88 #ifdef ABORT_ON_TYPE_MISMATCH
89   abort();
90 #endif
92 @endcode
94 The usage of talloc_get_type_abort() would be then:
96 @code
97 talloc_set_abort_fn(my_abort);
99 TALLOC_CTX *ctx = talloc_new(NULL);
100 char *str = talloc_get_type_abort(ctx, char);
101 if (str == NULL) {
102   /* recovery code */
104 /* talloc abort: ../src/main.c:25: Type mismatch:
105    name[talloc_new: ../src/main.c:24] expected[char] */
106 @endcode