1libtalloc_dts(3)                    talloc                    libtalloc_dts(3)
2
3
4

NAME

6       libtalloc_dts - Chapter 3: Dynamic type system
7
8

Dynamic type system

10       Generic programming in the C language is very difficult. There is no
11       inheritance nor templates known from object oriented languages. There
12       is no dynamic type system. Therefore, generic programming in this
13       language is usually done by type-casting a variable to void* and
14       transferring it through a generic function to a specialized callback as
15       illustrated on the next listing.
16
17       void generic_function(callback_fn cb, void *pvt)
18       {
19         /* do some stuff and call the callback */
20         cb(pvt);
21       }
22
23       void specific_callback(void *pvt)
24       {
25         struct specific_struct *data;
26         data = (struct specific_struct*)pvt;
27         /* ... */
28       }
29
30       void specific_function()
31       {
32         struct specific_struct data;
33         generic_function(callback, &data);
34       }
35
36       Unfortunately, the type information is lost as a result of this type
37       cast. The compiler cannot check the type during the compilation nor are
38       we able to do it at runtime. Providing an invalid data type to the
39       callback will result in unexpected behaviour (not necessarily a crash)
40       of the application. This mistake is usually hard to detect because it
41       is not the first thing which comes the mind.
42
43       As we already know, every talloc context contains a name. This name is
44       available at any time and it can be used to determine the type of a
45       context even if we lose the type of a variable.
46
47       Although the name of the context can be set to any arbitrary string,
48       the best way of using it to simulate the dynamic type system is to set
49       it directly to the type of the variable.
50
51       It is recommended to use one of talloc() and talloc_array() (or its
52       variants) to create the context as they set its name to the name of the
53       given type automatically.
54
55       If we have a context with such as a name, we can use two similar
56       functions that do both the type check and the type cast for us:
57
58       · talloc_get_type()
59
60       · talloc_get_type_abort()
61

Examples

63       The following example will show how generic programming with talloc is
64       handled - if we provide invalid data to the callback, the program will
65       be aborted. This is a sufficient reaction for such an error in most
66       applications.
67
68       void foo_callback(void *pvt)
69       {
70         struct foo *data = talloc_get_type_abort(pvt, struct foo);
71         /* ... */
72       }
73
74       int do_foo()
75       {
76         struct foo *data = talloc_zero(NULL, struct foo);
77         /* ... */
78         return generic_function(foo_callback, data);
79       }
80
81       But what if we are creating a service application that should be
82       running for the uptime of a server, we may want to abort the
83       application during the development process (to make sure the error is
84       not overlooked) and try to recover from the error in the customer
85       release. This can be achieved by creating a custom abort function with
86       a conditional build.
87
88       void my_abort(const char *reason)
89       {
90         fprintf(stderr, "talloc abort: %s0, reason);
91       #ifdef ABORT_ON_TYPE_MISMATCH
92         abort();
93       #endif
94       }
95
96       The usage of talloc_get_type_abort() would be then:
97
98       talloc_set_abort_fn(my_abort);
99
100       TALLOC_CTX *ctx = talloc_new(NULL);
101       char *str = talloc_get_type_abort(ctx, char);
102       if (str == NULL) {
103         /* recovery code */
104       }
105       /* talloc abort: ../src/main.c:25: Type mismatch:
106          name[talloc_new: ../src/main.c:24] expected[char] */
107
108Version 2.0                     Sat May 11 2019               libtalloc_dts(3)
Impressum