| # Initialization | |
| Outside of the Wuffs base package, every Wuffs struct has an implicit | |
| `initialize` method, which needs to be called before any other method. In | |
| Wuffs' C language form, the `initialize` function for the `foo` package's `bar` | |
| struct is called `wuffs_foo__bar__initialize`. The function takes four | |
| arguments (or, in C++, the `initialize` method takes three arguments, with the | |
| implicit `this` pointer argument): | |
| - A pointer to the `wuffs_foo__bar` object: the `this` pointer. | |
| - The size (in bytes) of that object. Conceptually, this is | |
| `sizeof(wuffs_foo__bar{})`, but that expression generally won't compile, as | |
| `wuffs_foo__bar` is deliberately an incomplete type. Its size is not part of | |
| the stable ABI. Instead, call the `sizeof__wuffs_foo__bar` *function*, whose | |
| return value can change across Wuffs versions, even across point releases. | |
| For an example, look for `sizeof__wuffs_json__decoder` in the | |
| [example/jsonptr](/example/jsonptr/jsonptr.cc) program. | |
| - The Wuffs library version, `WUFFS_VERSION`. | |
| - Additional flags. | |
| Initialization can fail if the caller and callee disagree on the size or the | |
| Wuffs version, or if unsupported flag bits are passed. | |
| There are no destructor functions. Just free the memory. Wuffs structs don't | |
| store or otherwise own file descriptors, pointers to dynamically allocated | |
| memory or anything else that needs explicit releasing. | |
| As a consequence, to restore a Wuffs object to its initial state (e.g. to | |
| re-use a Wuffs image decoder's memory to decode a different image), just call | |
| the `initialize` function again. | |
| ## Flags | |
| The flags are a bitmask of options. Zero (or equivalently, | |
| `WUFFS_INITIALIZE__DEFAULT_OPTIONS`) means that none of the options are set. | |
| - The `WUFFS_INITIALIZE__ALREADY_ZEROED` bit tells the `initialize` function to | |
| assume that the entire struct has already been zero-initialized. This can | |
| make the `initialize` call a little faster. | |
| - The `WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED` bit means to | |
| partially, not fully, zero-initialize the struct. Again, this can make the | |
| call a little faster. See the "Partial Zero-Initialization" section below for | |
| details. This bit is ignored if the `WUFFS_INITIALIZE__ALREADY_ZEROED` bit is | |
| also set. | |
| ## Partial Zero-Initialization | |
| Memory-safe programming languages typically initialize their variables and | |
| fields to zero, so that there is no way to read an uninitialized value. By | |
| default, Wuffs does so too, but in Wuffs' C/C++ form, there is the option (the | |
| `WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED` flag bit) to leave | |
| some struct fields uninitialized (although local variables are always | |
| zero-initialized), for performance reasons. | |
| With or without this flag bit set, the Wuffs compiler still enforces bounds and | |
| arithmetic overflow checks. It's just that for potentially-uninitialized struct | |
| fields, the compiler has weaker starting assumptions: their numeric types | |
| cannot be [refined](/doc/glossary.md#refinement-type). | |
| Even with this flag bit set, the Wuffs standard library also considers reading | |
| from an uninitialized buffer to be a bug, and strives to never do so, but | |
| unlike buffer out-of-bounds reads or writes, it is not a bug class that the | |
| Wuffs compiler eliminates. | |
| For those paranoid about security, leave this flag bit unset, so that | |
| `wuffs_foo__bar__initialize` will zero-initialize the entire struct (unless the | |
| `WUFFS_INITIALIZE__ALREADY_ZEROED` flag bit is also set). | |
| Setting this flag bit (avoiding a fixed-size cost) gives a small absolute | |
| improvement on micro-benchmarks, mostly noticeable (in relative terms) only | |
| when the actual work to do (the input) is also small. Look for | |
| `WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED` in the | |
| [benchmarks](/doc/benchmarks.md) for performance numbers. | |
| In Wuffs code, a struct definition has two parts, although the second part's | |
| `()` parentheses may be omitted if empty: | |
| ``` | |
| pub struct bar?( | |
| // Fields in the first part are always zero-initialized. | |
| x : etc, | |
| y : etc, | |
| )( | |
| // Fields in the second part are optionally uninitialized, but are still | |
| // zero-initialized by default. | |
| // | |
| // Valid types for these fields are either unrefined numerical types, or | |
| // arrays of a valid type. | |
| // - "base.u8" is ok. | |
| // - "array[123] base.u8" is ok. | |
| // - "array[123] base.u8[0 ..= 99]" is not, due to the refinement. | |
| z : etc, | |
| ) | |
| ``` |