2017-10-08 21:25:19 +02:00
|
|
|
|
# C++ Style Guide
|
|
|
|
|
|
2019-11-20 00:57:49 +01:00
|
|
|
|
See also the [C++ codebase README](src/README.md) for C++ idioms in the Node.js
|
|
|
|
|
codebase not related to stylistic issues.
|
|
|
|
|
|
2017-11-15 18:05:23 +01:00
|
|
|
|
## Table of Contents
|
|
|
|
|
|
2018-10-08 01:07:57 +02:00
|
|
|
|
* [Guides and References](#guides-and-references)
|
2017-11-17 11:00:31 +01:00
|
|
|
|
* [Formatting](#formatting)
|
|
|
|
|
* [Left-leaning (C++ style) asterisks for pointer declarations](#left-leaning-c-style-asterisks-for-pointer-declarations)
|
2017-12-11 20:25:09 +01:00
|
|
|
|
* [C++ style comments](#c-style-comments)
|
2017-11-17 11:00:31 +01:00
|
|
|
|
* [2 spaces of indentation for blocks or bodies of conditionals](#2-spaces-of-indentation-for-blocks-or-bodies-of-conditionals)
|
|
|
|
|
* [4 spaces of indentation for statement continuations](#4-spaces-of-indentation-for-statement-continuations)
|
|
|
|
|
* [Align function arguments vertically](#align-function-arguments-vertically)
|
|
|
|
|
* [Initialization lists](#initialization-lists)
|
2017-12-05 04:56:43 +01:00
|
|
|
|
* [CamelCase for methods, functions, and classes](#camelcase-for-methods-functions-and-classes)
|
2017-11-17 11:00:31 +01:00
|
|
|
|
* [snake\_case for local variables and parameters](#snake_case-for-local-variables-and-parameters)
|
|
|
|
|
* [snake\_case\_ for private class fields](#snake_case_-for-private-class-fields)
|
2019-01-01 16:05:59 +01:00
|
|
|
|
* [snake\_case for C-like structs](#snake_case-for-c-like-structs)
|
2017-11-17 11:00:31 +01:00
|
|
|
|
* [Space after `template`](#space-after-template)
|
|
|
|
|
* [Memory Management](#memory-management)
|
|
|
|
|
* [Memory allocation](#memory-allocation)
|
|
|
|
|
* [Use `nullptr` instead of `NULL` or `0`](#use-nullptr-instead-of-null-or-0)
|
2018-10-21 18:55:30 +02:00
|
|
|
|
* [Use explicit pointer comparisons](#use-explicit-pointer-comparisons)
|
2017-11-17 11:00:31 +01:00
|
|
|
|
* [Ownership and Smart Pointers](#ownership-and-smart-pointers)
|
2018-09-22 20:43:53 +02:00
|
|
|
|
* [Avoid non-const references](#avoid-non-const-references)
|
2018-11-29 15:23:28 +01:00
|
|
|
|
* [Use AliasedBuffers to manipulate TypedArrays](#use-aliasedbuffers-to-manipulate-typedarrays)
|
2017-11-17 11:00:31 +01:00
|
|
|
|
* [Others](#others)
|
|
|
|
|
* [Type casting](#type-casting)
|
2018-09-22 20:43:53 +02:00
|
|
|
|
* [Using `auto`](#using-auto)
|
2017-11-17 11:00:31 +01:00
|
|
|
|
* [Do not include `*.h` if `*-inl.h` has already been included](#do-not-include-h-if--inlh-has-already-been-included)
|
2018-01-14 19:51:36 +01:00
|
|
|
|
* [Avoid throwing JavaScript errors in C++ methods](#avoid-throwing-javascript-errors-in-c)
|
|
|
|
|
* [Avoid throwing JavaScript errors in nested C++ methods](#avoid-throwing-javascript-errors-in-nested-c-methods)
|
2017-11-15 18:05:23 +01:00
|
|
|
|
|
2018-10-08 01:07:57 +02:00
|
|
|
|
## Guides and References
|
|
|
|
|
|
|
|
|
|
The Node.js C++ codebase strives to be consistent in its use of language
|
|
|
|
|
features and idioms, as well as have some specific guidelines for the use of
|
|
|
|
|
runtime features.
|
|
|
|
|
|
|
|
|
|
Coding guidelines are based on the following guides (highest priority first):
|
2019-09-06 07:42:22 +02:00
|
|
|
|
|
2018-10-08 01:07:57 +02:00
|
|
|
|
1. This document
|
|
|
|
|
2. The [Google C++ Style Guide][]
|
|
|
|
|
3. The ISO [C++ Core Guidelines][]
|
|
|
|
|
|
|
|
|
|
In general code should follow the C++ Core Guidelines, unless overridden by the
|
|
|
|
|
Google C++ Style Guide or this document. At the moment these guidelines are
|
|
|
|
|
checked manually by reviewers, with the goal to validate this with automatic
|
|
|
|
|
tools.
|
2017-10-08 21:25:19 +02:00
|
|
|
|
|
2017-11-17 11:00:31 +01:00
|
|
|
|
## Formatting
|
|
|
|
|
|
2018-10-08 01:07:57 +02:00
|
|
|
|
Unfortunately, the C++ linter (based on [Google’s `cpplint`][]), which can be
|
|
|
|
|
run explicitly via `make lint-cpp`, does not currently catch a lot of rules that
|
|
|
|
|
are specific to the Node.js C++ code base. This document explains the most
|
|
|
|
|
common of these rules:
|
|
|
|
|
|
2018-09-22 20:37:32 +02:00
|
|
|
|
### Left-leaning (C++ style) asterisks for pointer declarations
|
2017-10-08 21:25:19 +02:00
|
|
|
|
|
|
|
|
|
`char* buffer;` instead of `char *buffer;`
|
|
|
|
|
|
2018-09-22 20:37:32 +02:00
|
|
|
|
### C++ style comments
|
2017-12-11 20:25:09 +01:00
|
|
|
|
|
|
|
|
|
Use C++ style comments (`//`) for both single-line and multi-line comments.
|
|
|
|
|
Comments should also start with uppercase and finish with a dot.
|
|
|
|
|
|
|
|
|
|
Examples:
|
|
|
|
|
|
|
|
|
|
```c++
|
|
|
|
|
// A single-line comment.
|
|
|
|
|
|
|
|
|
|
// Multi-line comments
|
|
|
|
|
// should also use C++
|
|
|
|
|
// style comments.
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
The codebase may contain old C style comments (`/* */`) from before this was the
|
|
|
|
|
preferred style. Feel free to update old comments to the preferred style when
|
|
|
|
|
working on code in the immediate vicinity or when changing/improving those
|
|
|
|
|
comments.
|
|
|
|
|
|
2018-09-22 20:37:32 +02:00
|
|
|
|
### 2 spaces of indentation for blocks or bodies of conditionals
|
2017-10-08 21:25:19 +02:00
|
|
|
|
|
|
|
|
|
```c++
|
|
|
|
|
if (foo)
|
|
|
|
|
bar();
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
or
|
|
|
|
|
|
|
|
|
|
```c++
|
|
|
|
|
if (foo) {
|
|
|
|
|
bar();
|
|
|
|
|
baz();
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Braces are optional if the statement body only has one line.
|
|
|
|
|
|
|
|
|
|
`namespace`s receive no indentation on their own.
|
|
|
|
|
|
2018-09-22 20:37:32 +02:00
|
|
|
|
### 4 spaces of indentation for statement continuations
|
2017-10-08 21:25:19 +02:00
|
|
|
|
|
|
|
|
|
```c++
|
|
|
|
|
VeryLongTypeName very_long_result = SomeValueWithAVeryLongName +
|
|
|
|
|
SomeOtherValueWithAVeryLongName;
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Operators are before the line break in these cases.
|
|
|
|
|
|
2018-09-22 20:37:32 +02:00
|
|
|
|
### Align function arguments vertically
|
2017-10-08 21:25:19 +02:00
|
|
|
|
|
|
|
|
|
```c++
|
|
|
|
|
void FunctionWithAVeryLongName(int parameter_with_a_very_long_name,
|
|
|
|
|
double other_parameter_with_a_very_long_name,
|
|
|
|
|
...);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
If that doesn’t work, break after the `(` and use 4 spaces of indentation:
|
|
|
|
|
|
|
|
|
|
```c++
|
|
|
|
|
void FunctionWithAReallyReallyReallyLongNameSeriouslyStopIt(
|
|
|
|
|
int okay_there_is_no_space_left_in_the_previous_line,
|
|
|
|
|
...);
|
|
|
|
|
```
|
|
|
|
|
|
2018-09-22 20:37:32 +02:00
|
|
|
|
### Initialization lists
|
2017-10-08 21:25:19 +02:00
|
|
|
|
|
|
|
|
|
Long initialization lists are formatted like this:
|
|
|
|
|
|
|
|
|
|
```c++
|
|
|
|
|
HandleWrap::HandleWrap(Environment* env,
|
|
|
|
|
Local<Object> object,
|
|
|
|
|
uv_handle_t* handle,
|
|
|
|
|
AsyncWrap::ProviderType provider)
|
|
|
|
|
: AsyncWrap(env, object, provider),
|
|
|
|
|
state_(kInitialized),
|
|
|
|
|
handle_(handle) {
|
|
|
|
|
```
|
|
|
|
|
|
2018-09-22 20:37:32 +02:00
|
|
|
|
### CamelCase for methods, functions, and classes
|
2017-10-08 21:25:19 +02:00
|
|
|
|
|
|
|
|
|
Exceptions are simple getters/setters, which are named `property_name()` and
|
|
|
|
|
`set_property_name()`, respectively.
|
|
|
|
|
|
|
|
|
|
```c++
|
|
|
|
|
class FooBar {
|
|
|
|
|
public:
|
|
|
|
|
void DoSomething();
|
|
|
|
|
static void DoSomethingButItsStaticInstead();
|
|
|
|
|
|
|
|
|
|
void set_foo_flag(int flag_value);
|
|
|
|
|
int foo_flag() const; // Use const-correctness whenever possible.
|
|
|
|
|
};
|
|
|
|
|
```
|
|
|
|
|
|
2018-09-22 20:37:32 +02:00
|
|
|
|
### snake\_case for local variables and parameters
|
2017-10-08 21:25:19 +02:00
|
|
|
|
|
|
|
|
|
```c++
|
|
|
|
|
int FunctionThatDoesSomething(const char* important_string) {
|
|
|
|
|
const char* pointer_into_string = important_string;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2018-09-22 20:37:32 +02:00
|
|
|
|
### snake\_case\_ for private class fields
|
2017-10-08 21:25:19 +02:00
|
|
|
|
|
|
|
|
|
```c++
|
|
|
|
|
class Foo {
|
|
|
|
|
private:
|
|
|
|
|
int counter_ = 0;
|
|
|
|
|
};
|
|
|
|
|
```
|
|
|
|
|
|
2019-01-01 16:05:59 +01:00
|
|
|
|
### snake\_case for C-like structs
|
2018-05-02 08:59:35 +02:00
|
|
|
|
For plain C-like structs snake_case can be used.
|
|
|
|
|
|
|
|
|
|
```c++
|
|
|
|
|
struct foo_bar {
|
|
|
|
|
int name;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2018-09-22 20:37:32 +02:00
|
|
|
|
### Space after `template`
|
2017-10-08 21:25:19 +02:00
|
|
|
|
|
|
|
|
|
```c++
|
|
|
|
|
template <typename T>
|
|
|
|
|
class FancyContainer {
|
|
|
|
|
...
|
|
|
|
|
}
|
|
|
|
|
```
|
2019-08-29 15:28:03 +02:00
|
|
|
|
|
2017-11-17 11:00:31 +01:00
|
|
|
|
## Memory Management
|
2017-10-08 21:25:19 +02:00
|
|
|
|
|
2018-09-22 20:37:32 +02:00
|
|
|
|
### Memory allocation
|
2017-10-08 21:25:19 +02:00
|
|
|
|
|
2019-09-13 06:22:29 +02:00
|
|
|
|
* `Malloc()`, `Calloc()`, etc. from `util.h` abort in Out-of-Memory situations
|
|
|
|
|
* `UncheckedMalloc()`, etc. return `nullptr` in OOM situations
|
2017-10-08 21:25:19 +02:00
|
|
|
|
|
2018-09-22 20:37:32 +02:00
|
|
|
|
### Use `nullptr` instead of `NULL` or `0`
|
2017-10-08 21:25:19 +02:00
|
|
|
|
|
2018-10-14 03:06:41 +02:00
|
|
|
|
Further reading in the [C++ Core Guidelines][ES.47].
|
2017-10-08 21:25:19 +02:00
|
|
|
|
|
2018-10-21 18:55:30 +02:00
|
|
|
|
### Use explicit pointer comparisons
|
|
|
|
|
|
|
|
|
|
Use explicit comparisons to `nullptr` when testing pointers, i.e.
|
|
|
|
|
`if (foo == nullptr)` instead of `if (foo)` and
|
|
|
|
|
`foo != nullptr` instead of `!foo`.
|
|
|
|
|
|
2018-09-22 20:37:32 +02:00
|
|
|
|
### Ownership and Smart Pointers
|
2017-11-17 11:00:31 +01:00
|
|
|
|
|
2019-10-14 07:13:52 +02:00
|
|
|
|
* [R.20][]: Use `std::unique_ptr` or `std::shared_ptr` to represent ownership
|
|
|
|
|
* [R.21][]: Prefer `unique_ptr` over `shared_ptr` unless you need to share
|
2018-10-14 03:06:41 +02:00
|
|
|
|
ownership
|
|
|
|
|
|
|
|
|
|
Use `std::unique_ptr` to make ownership transfer explicit. For example:
|
2017-11-17 11:00:31 +01:00
|
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
|
std::unique_ptr<Foo> FooFactory();
|
|
|
|
|
void FooConsumer(std::unique_ptr<Foo> ptr);
|
|
|
|
|
```
|
|
|
|
|
|
2018-10-14 03:06:41 +02:00
|
|
|
|
Since `std::unique_ptr` has only move semantics, passing one by value transfers
|
|
|
|
|
ownership to the callee and invalidates the caller's instance.
|
|
|
|
|
|
|
|
|
|
Don't use `std::auto_ptr`, it is deprecated ([Reference][cppref_auto_ptr]).
|
2017-11-17 11:00:31 +01:00
|
|
|
|
|
2018-09-22 20:43:53 +02:00
|
|
|
|
### Avoid non-const references
|
|
|
|
|
|
|
|
|
|
Using non-const references often obscures which values are changed by an
|
|
|
|
|
assignment. Consider using a pointer instead, which requires more explicit
|
|
|
|
|
syntax to indicate that modifications take place.
|
|
|
|
|
|
|
|
|
|
```c++
|
|
|
|
|
class ExampleClass {
|
|
|
|
|
public:
|
|
|
|
|
explicit ExampleClass(OtherClass* other_ptr) : pointer_to_other_(other_ptr) {}
|
|
|
|
|
|
|
|
|
|
void SomeMethod(const std::string& input_param,
|
|
|
|
|
std::string* in_out_param); // Pointer instead of reference
|
|
|
|
|
|
|
|
|
|
const std::string& get_foo() const { return foo_string_; }
|
|
|
|
|
void set_foo(const std::string& new_value) { foo_string_ = new_value; }
|
|
|
|
|
|
|
|
|
|
void ReplaceCharacterInFoo(char from, char to) {
|
|
|
|
|
// A non-const reference is okay here, because the method name already tells
|
|
|
|
|
// users that this modifies 'foo_string_' -- if that is not the case,
|
|
|
|
|
// it can still be better to use an indexed for loop, or leave appropriate
|
|
|
|
|
// comments.
|
|
|
|
|
for (char& character : foo_string_) {
|
|
|
|
|
if (character == from)
|
|
|
|
|
character = to;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
std::string foo_string_;
|
|
|
|
|
// Pointer instead of reference. If this object 'owns' the other object,
|
|
|
|
|
// this should be a `std::unique_ptr<OtherClass>`; a
|
|
|
|
|
// `std::shared_ptr<OtherClass>` can also be a better choice.
|
|
|
|
|
OtherClass* pointer_to_other_;
|
|
|
|
|
};
|
|
|
|
|
```
|
|
|
|
|
|
2018-11-29 15:23:28 +01:00
|
|
|
|
### Use AliasedBuffers to manipulate TypedArrays
|
|
|
|
|
|
|
|
|
|
When working with typed arrays that involve direct data modification
|
|
|
|
|
from C++, use an `AliasedBuffer` when possible. The API abstraction and
|
|
|
|
|
the usage scope of `AliasedBuffer` are documented in [aliased_buffer.h][].
|
|
|
|
|
|
|
|
|
|
```c++
|
|
|
|
|
// Create an AliasedBuffer.
|
|
|
|
|
AliasedBuffer<uint32_t, v8::Uint32Array> data;
|
|
|
|
|
...
|
|
|
|
|
|
|
|
|
|
// Modify the data through natural operator semantics.
|
|
|
|
|
data[0] = 12345;
|
|
|
|
|
```
|
|
|
|
|
|
2017-11-17 11:00:31 +01:00
|
|
|
|
## Others
|
|
|
|
|
|
2018-09-22 20:37:32 +02:00
|
|
|
|
### Type casting
|
2017-11-17 11:00:31 +01:00
|
|
|
|
|
2019-09-13 06:22:29 +02:00
|
|
|
|
* Use `static_cast<T>` if casting is required, and it is valid
|
|
|
|
|
* Use `reinterpret_cast` only when it is necessary
|
|
|
|
|
* Avoid C-style casts (`(type)value`)
|
|
|
|
|
* `dynamic_cast` does not work because Node.js is built without
|
2018-10-14 03:06:41 +02:00
|
|
|
|
[Run Time Type Information][]
|
|
|
|
|
|
|
|
|
|
Further reading:
|
2019-09-06 07:42:22 +02:00
|
|
|
|
|
2019-10-14 07:13:52 +02:00
|
|
|
|
* [ES.48][]: Avoid casts
|
|
|
|
|
* [ES.49][]: If you must use a cast, use a named cast
|
2017-11-17 11:00:31 +01:00
|
|
|
|
|
2018-09-22 20:43:53 +02:00
|
|
|
|
### Using `auto`
|
|
|
|
|
|
|
|
|
|
Being explicit about types is usually preferred over using `auto`.
|
|
|
|
|
|
|
|
|
|
Use `auto` to avoid type names that are noisy, obvious, or unimportant. When
|
|
|
|
|
doing so, keep in mind that explicit types often help with readability and
|
|
|
|
|
verifying the correctness of code.
|
|
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
|
for (const auto& item : some_map) {
|
|
|
|
|
const KeyType& key = item.first;
|
|
|
|
|
const ValType& value = item.second;
|
|
|
|
|
// The rest of the loop can now just refer to key and value,
|
|
|
|
|
// a reader can see the types in question, and we've avoided
|
|
|
|
|
// the too-common case of extra copies in this iteration.
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2018-09-22 20:37:32 +02:00
|
|
|
|
### Do not include `*.h` if `*-inl.h` has already been included
|
2017-10-27 10:30:31 +02:00
|
|
|
|
|
|
|
|
|
Do
|
|
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
|
#include "util-inl.h" // already includes util.h
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
instead of
|
|
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
|
#include "util.h"
|
|
|
|
|
#include "util-inl.h"
|
|
|
|
|
```
|
|
|
|
|
|
2018-09-22 20:37:32 +02:00
|
|
|
|
### Avoid throwing JavaScript errors in C++
|
2017-10-08 21:25:19 +02:00
|
|
|
|
|
2018-01-14 19:51:36 +01:00
|
|
|
|
When there is a need to throw errors from a C++ binding method, try to
|
|
|
|
|
return the data necessary for constructing the errors to JavaScript,
|
|
|
|
|
then construct and throw the errors [using `lib/internal/errors.js`][errors].
|
2017-10-08 21:25:19 +02:00
|
|
|
|
|
2019-06-20 21:22:34 +02:00
|
|
|
|
In general, type-checks on arguments should be done in JavaScript
|
2018-01-14 19:51:36 +01:00
|
|
|
|
before the arguments are passed into C++. Then in the C++ binding, simply using
|
|
|
|
|
`CHECK` assertions to guard against invalid arguments should be enough.
|
|
|
|
|
|
|
|
|
|
If the return value of the binding cannot be used to signal failures or return
|
|
|
|
|
the necessary data for constructing errors in JavaScript, pass a context object
|
|
|
|
|
to the binding and put the necessary data inside in C++. For example:
|
|
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
|
void Foo(const FunctionCallbackInfo<Value>& args) {
|
|
|
|
|
Environment* env = Environment::GetCurrent(args);
|
|
|
|
|
// Let the JavaScript handle the actual type-checking,
|
|
|
|
|
// only assertions are placed in C++
|
|
|
|
|
CHECK_EQ(args.Length(), 2);
|
|
|
|
|
CHECK(args[0]->IsString());
|
|
|
|
|
CHECK(args[1]->IsObject());
|
|
|
|
|
|
|
|
|
|
int err = DoSomethingWith(args[0].As<String>());
|
|
|
|
|
if (err) {
|
|
|
|
|
// Put the data inside the error context
|
|
|
|
|
Local<Object> ctx = args[1].As<Object>();
|
|
|
|
|
Local<String> key = FIXED_ONE_BYTE_STRING(env->isolate(), "code");
|
|
|
|
|
ctx->Set(env->context(), key, err).FromJust();
|
|
|
|
|
} else {
|
|
|
|
|
args.GetReturnValue().Set(something_to_return);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// In the initialize function
|
|
|
|
|
env->SetMethod(target, "foo", Foo);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```js
|
|
|
|
|
exports.foo = function(str) {
|
|
|
|
|
// Prefer doing the type-checks in JavaScript
|
|
|
|
|
if (typeof str !== 'string') {
|
2018-03-06 14:23:36 +01:00
|
|
|
|
throw new errors.codes.ERR_INVALID_ARG_TYPE('str', 'string');
|
2018-01-14 19:51:36 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const ctx = {};
|
|
|
|
|
const result = binding.foo(str, ctx);
|
|
|
|
|
if (ctx.code !== undefined) {
|
2018-03-06 14:23:36 +01:00
|
|
|
|
throw new errors.codes.ERR_ERROR_NAME(ctx.code);
|
2018-01-14 19:51:36 +01:00
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
};
|
|
|
|
|
```
|
|
|
|
|
|
2018-09-22 20:37:32 +02:00
|
|
|
|
#### Avoid throwing JavaScript errors in nested C++ methods
|
2018-01-14 19:51:36 +01:00
|
|
|
|
|
2018-10-14 03:06:41 +02:00
|
|
|
|
When you need to throw a JavaScript exception from C++ (i.e.
|
|
|
|
|
`isolate()->ThrowException()`) prefer to do it as close to the return to JS as
|
|
|
|
|
possible, and not inside of nested C++ calls. Since this changes the JS
|
|
|
|
|
execution state doing it closest to where it is consumed reduces the chances of
|
|
|
|
|
side effects.
|
2017-10-08 21:25:19 +02:00
|
|
|
|
|
2018-10-14 03:06:41 +02:00
|
|
|
|
Node.js is built [without C++ exception handling][], so code using `throw` or
|
|
|
|
|
even `try` and `catch` **will** break.
|
2018-01-14 19:51:36 +01:00
|
|
|
|
|
2018-10-08 01:07:57 +02:00
|
|
|
|
[C++ Core Guidelines]: http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines
|
|
|
|
|
[Google C++ Style Guide]: https://google.github.io/styleguide/cppguide.html
|
|
|
|
|
[Google’s `cpplint`]: https://github.com/google/styleguide
|
2018-01-14 19:51:36 +01:00
|
|
|
|
[errors]: https://github.com/nodejs/node/blob/master/doc/guides/using-internal-errors.md
|
2018-10-14 03:06:41 +02:00
|
|
|
|
[ES.47]: http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-nullptr
|
|
|
|
|
[ES.48]: http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-casts
|
|
|
|
|
[ES.49]: http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-casts-named
|
|
|
|
|
[R.20]: http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rr-owner
|
|
|
|
|
[R.21]: http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rr-unique
|
|
|
|
|
[Run Time Type Information]: https://en.wikipedia.org/wiki/Run-time_type_information
|
|
|
|
|
[cppref_auto_ptr]: https://en.cppreference.com/w/cpp/memory/auto_ptr
|
|
|
|
|
[without C++ exception handling]: https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_exceptions.html#intro.using.exception.no
|
2018-11-29 15:23:28 +01:00
|
|
|
|
[aliased_buffer.h]: https://github.com/nodejs/node/blob/master/src/aliased_buffer.h#L12
|