Changeset View
Changeset View
Standalone View
Standalone View
doc/developer-notes.md
Show First 20 Lines • Show All 584 Lines • ▼ Show 20 Lines | - *Rationale*: Behavior is undefined. In C++ parlor this means "may reformat | ||||
the universe", in practice this has resulted in at least one hard-to-debug crash bug | the universe", in practice this has resulted in at least one hard-to-debug crash bug | ||||
- Watch out for out-of-bounds vector access. `&vch[vch.size()]` is illegal, | - Watch out for out-of-bounds vector access. `&vch[vch.size()]` is illegal, | ||||
including `&vch[0]` for an empty vector. Use `vch.data()` and `vch.data() + | including `&vch[0]` for an empty vector. Use `vch.data()` and `vch.data() + | ||||
vch.size()` instead. | vch.size()` instead. | ||||
- Vector bounds checking is only enabled in debug mode. Do not rely on it | - Vector bounds checking is only enabled in debug mode. Do not rely on it | ||||
- Make sure that constructors initialize all fields. If this is skipped for a | - Initialize all non-static class members where they are defined. | ||||
good reason (i.e., optimization on the critical path), add an explicit | If this is skipped for a good reason (i.e., optimization on the critical | ||||
comment about this | path), add an explicit comment about this | ||||
- *Rationale*: Ensure determinism by avoiding accidental use of uninitialized | - *Rationale*: Ensure determinism by avoiding accidental use of uninitialized | ||||
values. Also, static analyzers balk about this. | values. Also, static analyzers balk about this. | ||||
Initializing the members in the declaration makes it easy to | |||||
spot uninitialized ones. | |||||
```cpp | |||||
class A | |||||
{ | |||||
uint32_t m_count{0}; | |||||
} | |||||
``` | |||||
- By default, declare single-argument constructors `explicit`. | - By default, declare single-argument constructors `explicit`. | ||||
- *Rationale*: This is a precaution to avoid unintended conversions that might | - *Rationale*: This is a precaution to avoid unintended conversions that might | ||||
arise when single-argument constructors are used as implicit conversion | arise when single-argument constructors are used as implicit conversion | ||||
functions. | functions. | ||||
- Use explicitly signed or unsigned `char`s, or even better `uint8_t` and | - Use explicitly signed or unsigned `char`s, or even better `uint8_t` and | ||||
`int8_t`. Do not use bare `char` unless it is to pass to a third-party API. | `int8_t`. Do not use bare `char` unless it is to pass to a third-party API. | ||||
This type can be signed or unsigned depending on the architecture, which can | This type can be signed or unsigned depending on the architecture, which can | ||||
lead to interoperability problems or dangerous conditions such as | lead to interoperability problems or dangerous conditions such as | ||||
out-of-bounds array accesses | out-of-bounds array accesses | ||||
- Prefer explicit constructions over implicit ones that rely on 'magical' C++ behavior | - Prefer explicit constructions over implicit ones that rely on 'magical' C++ behavior | ||||
- *Rationale*: Easier to understand what is happening, thus easier to spot mistakes, even for those | - *Rationale*: Easier to understand what is happening, thus easier to spot mistakes, even for those | ||||
that are not language lawyers | that are not language lawyers | ||||
- Initialize all non-static class members where they are defined | |||||
- *Rationale*: Initializing the members in the declaration makes it easy to spot uninitialized ones, | |||||
and avoids accidentally reading uninitialized memory | |||||
```cpp | |||||
class A | |||||
{ | |||||
uint32_t m_count{0}; | |||||
} | |||||
``` | |||||
Strings and formatting | Strings and formatting | ||||
------------------------ | ------------------------ | ||||
- Use `std::string`, avoid C string manipulation functions | - Use `std::string`, avoid C string manipulation functions | ||||
- *Rationale*: C++ string handling is marginally safer, less scope for | - *Rationale*: C++ string handling is marginally safer, less scope for | ||||
buffer overflows and surprises with `\0` characters. Also some C string manipulations | buffer overflows and surprises with `\0` characters. Also some C string manipulations | ||||
tend to act differently depending on platform, or even the user locale | tend to act differently depending on platform, or even the user locale | ||||
▲ Show 20 Lines • Show All 523 Lines • Show Last 20 Lines |