2 @page libtalloc_dts Chapter 3: Dynamic type system
4 @section dts Dynamic type system
6 Generic programming in the C language is very difficult. There is no inheritance
7 nor templates known from object oriented languages. There is no dynamic type
8 system. Therefore, generic programming in this language is usually done by
9 type-casting a variable to <code>void*</code> and transferring it through
10 a generic function to a specialized callback as illustrated on the next listing.
13 void generic_function(callback_fn cb, void *pvt)
15 /* do some stuff and call the callback */
19 void specific_callback(void *pvt)
21 struct specific_struct *data;
22 data = (struct specific_struct*)pvt;
26 void specific_function()
28 struct specific_struct data;
29 generic_function(callback, &data);
33 Unfortunately, the type information is lost as a result of this type cast. The
34 compiler cannot check the type during the compilation nor are we able to do it
35 at runtime. Providing an invalid data type to the callback will result in
36 unexpected behaviour (not necessarily a crash) of the application. This mistake
37 is usually hard to detect because it is not the first thing which comes the
40 As we already know, every talloc context contains a name. This name is available
41 at any time and it can be used to determine the type of a context even if we
42 lose the type of a variable.
44 Although the name of the context can be set to any arbitrary string, the best
45 way of using it to simulate the dynamic type system is to set it directly to the
48 It is recommended to use one of talloc() and talloc_array() (or its
49 variants) to create the context as they set its name to the name of the
50 given type automatically.
52 If we have a context with such as a name, we can use two similar functions that
53 do both the type check and the type cast for us:
56 - talloc_get_type_abort()
58 @section dts-examples Examples
60 The following example will show how generic programming with talloc is handled -
61 if we provide invalid data to the callback, the program will be aborted. This
62 is a sufficient reaction for such an error in most applications.
65 void foo_callback(void *pvt)
67 struct foo *data = talloc_get_type_abort(pvt, struct foo);
73 struct foo *data = talloc_zero(NULL, struct foo);
75 return generic_function(foo_callback, data);
79 But what if we are creating a service application that should be running for the
80 uptime of a server, we may want to abort the application during the development
81 process (to make sure the error is not overlooked) and try to recover from the
82 error in the customer release. This can be achieved by creating a custom abort
83 function with a conditional build.
86 void my_abort(const char *reason)
88 fprintf(stderr, "talloc abort: %s\n", reason);
89 #ifdef ABORT_ON_TYPE_MISMATCH
95 The usage of talloc_get_type_abort() would be then:
98 talloc_set_abort_fn(my_abort);
100 TALLOC_CTX *ctx = talloc_new(NULL);
101 char *str = talloc_get_type_abort(ctx, char);
105 /* talloc abort: ../src/main.c:25: Type mismatch:
106 name[talloc_new: ../src/main.c:24] expected[char] */