Unless DuckDB/Lance requirements dictate otherwise, follow the defaults below. These are guidelines, not immutable constraints.
- Do not use
malloc, prefer the use of smart pointers. Keywordsnewanddeleteare a code smell. - Strongly prefer the use of
unique_ptrovershared_ptr, only useshared_ptrif you absolutely have to. - Use
constwhenever possible. - Do not import namespaces (e.g.
using std). - All functions in source files in the core (
srcdirectory) should be part of theduckdbnamespace. - When overriding a virtual method, avoid repeating
virtualand always useoverrideorfinal. - Use
[u]int8_t/[u]int16_t/[u]int32_t/[u]int64_tinstead ofint,long,uintetc. Useidx_tinstead ofsize_tfor offsets/indices/counts of any kind. - Prefer using references over pointers as arguments.
- Use
constreferences for arguments of non-trivial objects (e.g.std::vector, ...). - Use C++11 for loops when possible:
for (const auto& item : items) {...}. - Use braces for
ifstatements and loops. Avoid single-lineifstatements and loops, especially nested ones. - Class layout should follow this structure:
class MyClass {
public:
MyClass();
int my_public_variable;
public:
void MyFunction();
private:
void MyPrivateFunction();
private:
int my_private_variable;
};- Avoid unnamed magic numbers. Use named variables stored in a
constexpr. - Return early and avoid deep nested branches.
- Do not include commented-out code blocks in pull requests.
- Use exceptions only when an error terminates a query (e.g. parser error, table not found).
- For expected/non-fatal errors, prefer return values over exceptions.
- Try to add test cases that trigger exceptions. If an exception cannot be easily triggered by tests, it may be an assertion instead.
- Use
D_ASSERTfor debug-only assertions (stripped in release builds). Useassertonly for invariants that must also be checked in release. - Assertions should never be triggerable by user input.
- Avoid assertions without context like
D_ASSERT(a > b + 3);unless accompanied by clear context/comments. - Assert liberally, and make clear (with concise comments when needed) what invariant failed.
- Choose descriptive names. Avoid single-letter variable names.
- Files: lowercase with underscores, e.g.
abstract_operator.cpp. - Types (classes, structs, enums, typedefs,
using):CamelCasestarting with uppercase, e.g.BaseColumn. - Variables: lowercase with underscores, e.g.
chunk_size. - Functions:
CamelCasestarting with uppercase, e.g.GetChunk. - Avoid
i,j, etc. in nested loops. Prefer names likecolumn_idx,check_idx. - In non-nested loops,
iis permissible as iterator index. - These rules are partially enforced by
clang-tidy.