Fix break by qualifying ptrdiff_t with std::.
[oota-llvm.git] / docs / CodingStandards.rst
index 18e832d51d9ede5be8ab17a9755356117fd2211f..a762bf358e3e8b8eb6ec5cd78d117be0808a02f9 100644 (file)
@@ -109,6 +109,9 @@ unlikely to be supported by our host compilers.
 * ``auto`` type deduction: N1984_, N1737_
 * Trailing return types: N2541_
 * Lambdas: N2927_
+
+  * But *not* ``std::function``, until Clang implements `MSVC-compatible RTTI`_.
+
 * ``decltype``: N2343_
 * Nested closing right angle brackets: N1757_
 * Extern templates: N1987_
@@ -138,6 +141,7 @@ unlikely to be supported by our host compilers.
 .. _N3206: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3206.htm
 .. _N3272: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3272.htm
 .. _N2429: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2429.htm
+.. _MSVC-compatible RTTI: http://llvm.org/PR18951
 
 The supported features in the C++11 standard libraries are less well tracked,
 but also much greater. Most of the standard libraries implement most of C++11's
@@ -153,6 +157,9 @@ being aware of:
 * While most of the atomics library is well implemented, the fences are
   missing. Fortunately, they are rarely needed.
 * The locale support is incomplete.
+* ``std::initializer_list`` (and the constructors and functions that take it as
+  an argument) are not always available, so you cannot (for example) initialize
+  a ``std::vector`` with a braced initializer list.
 
 Other than these areas you should assume the standard library is available and
 working as expected until some build bot tells you otherwise. If you're in an
@@ -481,6 +488,10 @@ by the preceding part of the statement:
     return a.bam < b.bam;
   });
 
+To take best advantage of this formatting, if you are designing an API which
+accepts a continuation or single callable argument (be it a functor, or
+a ``std::function``), it should be the last argument if at all possible.
+
 If there are multiple multi-line lambdas in a statement, or there is anything
 interesting after the lambda in the statement, indent the block two spaces from
 the indent of the ``[]``:
@@ -646,12 +657,38 @@ members public by default.
 
 Unfortunately, not all compilers follow the rules and some will generate
 different symbols based on whether ``class`` or ``struct`` was used to declare
-the symbol.  This can lead to problems at link time.
+the symbol (e.g., MSVC).  This can lead to problems at link time.
+
+* All declarations and definitions of a given ``class`` or ``struct`` must use
+  the same keyword.  For example:
+
+.. code-block:: c++
+
+  class Foo;
+
+  // Breaks mangling in MSVC.
+  struct Foo { int Data; };
+
+* As a rule of thumb, ``struct`` should be kept to structures where *all*
+  members are declared public.
+
+.. code-block:: c++
+
+  // Foo feels like a class... this is strange.
+  struct Foo {
+  private:
+    int Data;
+  public:
+    Foo() : Data(0) { }
+    int getData() const { return Data; }
+    void setData(int D) { Data = D; }
+  };
 
-So, the rule for LLVM is to always use the ``class`` keyword, unless **all**
-members are public and the type is a C++ `POD
-<http://en.wikipedia.org/wiki/Plain_old_data_structure>`_ type, in which case
-``struct`` is allowed.
+  // Bar isn't POD, but it does look like a struct.
+  struct Bar {
+    int Data;
+    Foo() : Data(0) { }
+  };
 
 Do not use Braced Initializer Lists to Call a Constructor
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -702,6 +739,27 @@ type is already obvious from the context. Another time when ``auto`` works well
 for these purposes is when the type would have been abstracted away anyways,
 often behind a container's typedef such as ``std::vector<T>::iterator``.
 
+Beware unnecessary copies with ``auto``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The convenience of ``auto`` makes it easy to forget that its default behavior
+is a copy.  Particularly in range-based ``for`` loops, careless copies are
+expensive.
+
+As a rule of thumb, use ``const auto &`` unless you need to mutate or copy the
+result.
+
+.. code-block:: c++
+
+  // Typically there's no reason to mutate or modify Val.
+  for (const auto &Val : Container) { observe(Val); }
+
+  // Remove the const if you need to modify Val.
+  for (auto &Val : Container) { Val.change(); }
+
+  // Remove the reference if you really want a new copy.
+  for (auto Val : Container) { Val.change(); saveSomewhere(Val); }
+
 Style Issues
 ============