Login
Changes To HackersGuide
Login

Changes to "HackersGuide" between 2014-02-05 18:25:58 and 2014-02-05 18:29:43

1
2
3
4
5

6
7

8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44
1
2
3
4

5
6

7
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

36
37
38
39
40
41
42
43
44




-
+

-
+








-
+



















-
+








<h1>Hacker's Guide</h1>

This page primarily contains notes for anyone who's actively hacking on libfossil internals, e.g. changing <tt>fsl_cx</tt>'s structure.

<h2>Introduction to structs...</h2>
<h2>An Introduction to structs...</h2>

For all (or almost all) structs in the library are accompanied by other constructs which help ensure consistency across how structs are to be initialized. The general pattern looks like this:
All (or almost all) structs in the library are accompanied by other constructs which help ensure (insure?) consistency regarding how library-level structs are to be initialized. The general pattern looks like this:

<nowiki><pre>
struct fsl_foo { ... };
typedef struct fsl_foo fsl_foo;
extern const fsl_foo_empty;
#define fsl_foo_empty_m { ...member initializers... }
</pre></nowiki>

The purpose of the macro is to have a const-initialized state for that struct. The <tt>fsl_foo_empty</tt> instance is guaranteed to be initialized using <tt>fsl_foo_empty_m</tt>, but both the "empty" and "empty_m" variants are provided because code requires different initializers in different contexts.
The purpose of the "empty_m" macro is to define a cleanly-initialized const state for that struct. The <tt>fsl_foo_empty</tt> instance is guaranteed to be initialized using <tt>fsl_foo_empty_m</tt>, but both the "empty" and "empty_m" variants are provided because code requires different initializers in different contexts (examples are provided below).

The "_m" suffix denotes "macro", by the way.

All non-opaque structs can and should be initialized in code like this:

<nowiki><pre>
fsl_buffer buf = fsl_buffer_empty;
fsl_deck deck = fsl_deck_empty;

// The "empty_m" macros are required mainly for in-struct initialization:
struct {
  fsl_buffer buf;
  fsl_deck deck;
} foo = {
  fsl_buffer_empty_m,
  fsl_deck_empty_m
};
</pre></nowiki>

That ensures that all struct members get set to known default values (which need not be NULL/0), and helps harden the code against uninitialized memory access (since all members get initialized to whatever the struct developer deemed sensible, and NULL is generally the sensible default for pointer members).
That ensures (insures?) that all struct members get set to known default values (which need not be NULL/0), and helps harden the code against uninitialized memory access (since all members get initialized to whatever the struct developer deemed sensible, and NULL is generally the sensible default for pointer members).


<h2>When updating structs...</h2>

When changing the members of structs, it is <em>critical</em> that the accompanying "empty_m" macro (described above) also be updated. Failing to do so can lead to undefined results (best case is a compilation failure when the shared struct "empty" instance is initialized from the "empty_m" macro).

<nowiki><pre>
</pre></nowiki>