diff --git a/CPP_STYLE_GUIDE.md b/CPP_STYLE_GUIDE.md index c717ca31724e5f..36c3538f418a55 100644 --- a/CPP_STYLE_GUIDE.md +++ b/CPP_STYLE_GUIDE.md @@ -192,40 +192,39 @@ class FancyContainer { ### Use `nullptr` instead of `NULL` or `0` -What it says in the title. +Further reading in the [C++ Core Guidelines][ES.47]. ### Ownership and Smart Pointers -"Smart" pointers are classes that act like pointers, e.g. -by overloading the `*` and `->` operators. Some smart pointer types can be -used to automate ownership bookkeeping, to ensure these responsibilities are -met. `std::unique_ptr` is a smart pointer type introduced in C++11, which -expresses exclusive ownership of a dynamically allocated object; the object -is deleted when the `std::unique_ptr` goes out of scope. It cannot be -copied, but can be moved to represent ownership transfer. -`std::shared_ptr` is a smart pointer type that expresses shared ownership of a -dynamically allocated object. `std::shared_ptr`s can be copied; ownership -of the object is shared among all copies, and the object -is deleted when the last `std::shared_ptr` is destroyed. - -Prefer to use `std::unique_ptr` to make ownership -transfer explicit. For example: +* [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 + ownership + +Use `std::unique_ptr` to make ownership transfer explicit. For example: ```cpp std::unique_ptr FooFactory(); void FooConsumer(std::unique_ptr ptr); ``` -Never use `std::auto_ptr`. Instead, use `std::unique_ptr`. +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]). ## Others ### Type casting -- Always avoid C-style casts (`(type)value`) -- `dynamic_cast` does not work because RTTI is not enabled -- Use `static_cast` for casting whenever it works -- `reinterpret_cast` is okay if `static_cast` is not appropriate +- Use `static_cast` 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 + [Run Time Type Information][] + +Further reading: +* [ES.48]: Avoid casts +* [ES.49]: If you must use a cast, use a named cast ### Using `auto` @@ -316,13 +315,25 @@ exports.foo = function(str) { #### Avoid throwing JavaScript errors in nested C++ methods -When you have to throw the errors from C++, try to do it at the top level and -not inside of nested calls. +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. -Using C++ `throw` is not allowed. +Node.js is built [without C++ exception handling][], so code using `throw` or +even `try` and `catch` **will** break. [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 [errors]: https://github.com/nodejs/node/blob/master/doc/guides/using-internal-errors.md +[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