diff --git a/cppguide.xml b/cppguide.xml index a0c2abf..9c381f5 100644 --- a/cppguide.xml +++ b/cppguide.xml @@ -4,7 +4,7 @@

-Revision 3.260 +Revision 3.274

@@ -412,6 +412,21 @@ Tashana Landray #include "base/commandlineflags.h" #include "foo/public/bar.h" +

+ Exception: sometimes, system-specific code needs conditional includes. + Such code can put conditional includes after other includes. + Of course, keep your system-specific code small and localized. + Example: +

+ + #include "foo/public/fooserver.h" + + #include "base/port.h" // For LANG_CXX11. + + #ifdef LANG_CXX11 + #include <initializer_list> + #endif // LANG_CXX11 + @@ -424,6 +439,7 @@ Tashana Landray project, and possibly its path. Do not use a using-directive. + Do not use inline namespaces. @@ -445,6 +461,22 @@ Tashana Landray and project2::Foo are now distinct symbols that do not collide.

+

+ Inline namespaces automatically place their names in the + enclosing scope. Consider the following snippet, for example: +

+ + namespace X { + inline namespace Y { + void foo(); + } + } + +

+ The expressions X::Y::foo() and + X::foo() are interchangeable. Inline namespaces + are primarily intended for ABI compatibility across versions. +

@@ -452,6 +484,12 @@ Tashana Landray additional (hierarchical) axis of naming, in addition to the (also hierarchical) name axis provided by classes.

+

+ Inline namespaces, in particular, can be confusing because + names aren't actually restricted to the namespace where they + are declared. They are only useful as part of some larger + versioning policy. +

Use of unnamed namespaces in header files can easily cause violations of the C++ One Definition Rule (ODR). @@ -608,6 +646,8 @@ Tashana Landray goal of keeping public APIs as small as possible.

+
  • Do not use inline namespaces. +
  • @@ -787,6 +827,8 @@ Tashana Landray Static or global variables of class type are forbidden: they cause hard-to-find bugs due to indeterminate order of construction and destruction. + However, such variables are allowed if they are constexpr: + they have no dynamic initialization or destruction.

    @@ -805,14 +847,30 @@ Tashana Landray itself depend on any other globals.

    - Likewise, the order in which destructors are called is defined to be the - reverse of the order in which the constructors were called. Since - constructor order is indeterminate, so is destructor order. - For example, at program-end time a static variable might have - been destroyed, but code still running -- perhaps in another thread -- - tries to access it and fails. Or the destructor for a static 'string' - variable might be run prior to the destructor for another variable that - contains a reference to that string. + Likewise, global and static variables are destroyed when the + program terminates, regardless of whether the termination is by + returning from main() or by calling + exit(). The order in which destructors are called is + defined to be the reverse of the order in which the constructors + were called. Since constructor order is indeterminate, so is + destructor order. For example, at program-end time a static + variable might have been destroyed, but code still running — + perhaps in another thread — tries to access it and fails. Or + the destructor for a static string variable might be + run prior to the destructor for another variable that contains a + reference to that string. +

    +

    + One way to alleviate the destructor problem is to terminate the + program by calling quick_exit() instead of + exit(). The difference is that quick_exit() + does not invoke destructors and does not invoke any handlers that were + registered by calling atexit(). If you have a handler that + needs to run when a program terminates via + quick_exit() (flushing logs, for example), you can + register it using at_quick_exit(). (If you have a handler + that needs to run at both exit() and + quick_exit(), you need to register it in both places.)

    As a result we only allow static variables to contain POD data. This @@ -888,32 +946,65 @@ Tashana Landray - +

    - You must define a default constructor if your class defines - member variables and has no other constructors. Otherwise the - compiler will do it for you, badly. + If your class defines member variables, you must provide an + in-class initializer for every member variable or write a constructor + (which can be a default constructor). If you do not declare + any constructors yourself then the compiler will generate a default + constructor for you, which may leave some fields uninitialized or + initialized to inappropriate values. - The default constructor is called when we new a - class object with no arguments. It is always called when - calling new[] (for arrays). + The default constructor is called when we new a class + object with no arguments. It is always called when calling + new[] (for arrays). In-class member initialization means + declaring a member variable using a construction like int count_ + = 17; or string name_{"abc"};, as opposed to just + int count_; or string name_;. - Initializing structures by default, to hold "impossible" - values, makes debugging much easier. +

    + A user defined default constructor is used to initialize an object + if no initializer is provided. It can ensure that an object is + always in a valid and usable state as soon as it's constructed; it + can also ensure that an object is initially created in an obviously + "impossible" state, to aid debugging. +

    +

    + In-class member initialization ensures that a member variable will + be initialized appropriately without having to duplicate the + initialization code in multiple constructors. This can reduce bugs + where you add a new member variable, initialize it in one + constructor, and forget to put that initialization code in another + constructor. +

    - Extra work for you, the code writer. +

    + Explicitly defining a default constructor is extra work for + you, the code writer. +

    +

    + In-class member initialization is potentially confusing if a member + variable is initialized as part of its declaration and also + initialized in a constructor, since the value in the constructor + will override the value in the declaration. +

    - If your class defines member variables and has no other - constructors you must define a default constructor (one that - takes no arguments). It should preferably initialize the - object in such a way that its internal state is consistent - and valid. + Use in-class member initialization for simple initializations, + especially when a member variable must be initialized the same way + in more than one constructor. +

    +

    + If your class defines member variables that aren't + initialized in-class, and if it has no other constructors, + you must define a default constructor (one that takes no + arguments). It should preferably initialize the object in + such a way that its internal state is consistent and valid.

    The reason for this is that if you have no other @@ -1068,6 +1159,90 @@ Tashana Landray + +

    + Use delegating and inheriting constructors + when they reduce code duplication. + + + +

    + Delegating and inheriting constructors are two different features, + both introduced in C++11, for reducing code duplication in + constructors. Delegating constructors allow one of a class's + constructors to forward work to one of the class's other + constructors, using a special variant of the initialization list + syntax. For example: +

    + + X::X(const string& name) : name_(name) { + ... + } + + X::X() : X("") { } + +

    + Inheriting constructors allow a derived class to have its base + class's constructors available directly, just as with any of the + base class's other member functions, instead of having to redeclare + them. This is especially useful if the base has multiple + constructors. For example: +

    + + class Base { + public: + Base(); + Base(int n); + Base(const string& s); + ... + }; + + class Derived : public Base { + public: + using Base::Base; // Base's constructors are redeclared here. + }; + +

    + This is especially useful when Derived's constructors + don't have to do anything more than calling Base's + constructors. +

    +
    + +

    + Delegating and inheriting constructors reduce verbosity + and boilerplate, which can improve readability. +

    +

    + Delegating constructors are familiar to Java programmers. +

    +
    + +

    + It's possible to approximate the behavior of delegating constructors + by using a helper function. +

    +

    + Inheriting constructors may be confusing if a derived class + introduces new member variables, since the base class constructor + doesn't know about them. +

    +
    + +

    + Use delegating and inheriting + constructors when they reduce boilerplate and improve + readability. Be cautious about inheriting + constructors when your derived class has new member variables. + Inheriting constructors may still be appropriate in that case + if you can use in-class member initialization for the derived + class's member variables. + +

    +
    + + + Use a struct only for passive objects that carry data; @@ -1274,21 +1449,32 @@ Tashana Landray Do not overload operators except in rare, special circumstances. + Do not create user-defined literals. A class can define that operators such as + and / operate on the class as if it were a built-in - type. + type. An overload of operator"" allows + the built-in literal syntax to be used to create objects of + class types. - Can make code appear more intuitive because a class will - behave in the same way as built-in types (such as - int). Overloaded operators are more playful - names for functions that are less-colorfully named, such as - Equals() or Add(). For some - template functions to work correctly, you may need to define - operators. +

    + Operator overloading can make code appear more intuitive because a + class will behave in the same way as built-in types (such as + int). Overloaded operators are more playful names for + functions that are less-colorfully named, such as + Equals() or Add(). +

    +

    + For some template functions to work correctly, you may need to + define operators. +

    +

    + User-defined literals are a very concise notation for creating + objects of user-defined types. +

    While operator overloading can make code more intuitive, it @@ -1308,6 +1494,9 @@ Tashana Landray different. The compiler does not complain for either of these, making this very hard to debug. +
  • User-defined literals allow creating new syntactic forms + that are unfamiliar even to experienced C++ programmers. +
  • Overloading also has surprising ramifications. For instance, if a class overloads unary operator&, it @@ -1323,6 +1512,10 @@ Tashana Landray unary operator& at all costs, if there's any possibility the class might be forward-declared.

    +

    + Do not overload operator"", i.e. + do not introduce user-defined literals. +

    However, there may be rare cases where you need to overload an operator to interoperate with templates or "standard" C++ @@ -1462,55 +1655,115 @@ Tashana Landray - - +

    - If you actually need pointer semantics, unique_ptr - is great, and scoped_ptr is fine if you need to support - older versions of C++. You should only use shared_ptr - with a non-const referent when it is truly necessary to share ownership - of an object (e.g. inside an STL container). You should never use - auto_ptr. + Prefer to have single, fixed owners for dynamically allocated objects. + Prefer to transfer ownership with smart pointers. - "Smart" pointers are objects that act like pointers, but automate - management of the underlying memory. +

    + "Ownership" is a bookkeeping technique for managing dynamically + allocated memory (and other resources). The owner of a dynamically + allocated object is an object or function that is responsible for + ensuring that it is deleted when no longer needed. Ownership can + sometimes be shared, in which case the last owner is typically + responsible for deleting it. Even when ownership is not shared, + it can be transferred from one piece of code to another. +

    +

    + "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. + shared_ptr is a smart pointer type which expresses + shared ownership of a dynamically allocated object. + shared_ptrs can be copied; ownership of the object is + shared among all copies, and the object is deleted when the last + shared_ptr is destroyed. +

    - Smart pointers are extremely useful for preventing memory leaks, and - are essential for writing exception-safe code. They also formalize - and document the ownership of dynamically allocated memory. +
      +
    • It's virtually impossible to manage dynamically allocated memory + without some sort of ownership logic.
    • +
    • Transferring ownership of an object can be cheaper than copying + it (if copying it is even possible).
    • +
    • Transferring ownership can be simpler than 'borrowing' a pointer + or reference, because it reduces the need to coordinate the + lifetime of the object between the two users.
    • +
    • Smart pointers can improve readability by making ownership logic + explicit, self-documenting, and unambiguous.
    • +
    • Smart pointers can eliminate manual ownership bookkeeping, + simplifying the code and ruling out large classes of errors.
    • +
    • For const objects, shared ownership can be a simple and efficient + alternative to deep copying.
    • +
    - We prefer designs in which objects have single, fixed owners. Smart - pointers which enable sharing or transfer of ownership can act as a - tempting alternative to a careful design of ownership semantics, - leading to confusing code and even bugs in which memory is never - deleted. The semantics of smart pointers (especially - auto_ptr) can be nonobvious and confusing. The - exception-safety benefits of smart pointers are not decisive, since - we do not allow exceptions. +
      +
    • Ownership must be represented and transferred via pointers + (whether smart or plain). Pointer semantics are more complicated + than value semantics, especially in APIs: you have to worry not + just about ownership, but also aliasing, lifetime, and mutability, + among other issues.
    • +
    • The performance costs of value semantics are often overestimated, + so the performance benefits of ownership transfer might not justify + the readability and complexity costs.
    • +
    • APIs that transfer ownership force their clients into a single + memory management model.
    • +
    • Code using smart pointers is less explicit about where the + resource releases take place.
    • +
    • std::unique_ptr expresses ownership transfer + using C++11's move semantics, which are + generally forbidden in Google + code, and may confuse some programmers.
    • +
    • Shared ownership can be a tempting alternative to careful + ownership design, obfuscating the design of a system.
    • +
    • Shared ownership requires explicit bookkeeping at run-time, + which can be costly.
    • +
    • In some cases (e.g. cyclic references), objects with shared + ownership may never be deleted.
    • +
    • Smart pointers are not perfect substitutes for plain + pointers.
    • +
    -
    -
    unique_ptr
    -
    See below.
    -
    scoped_ptr
    -
    Prefer unique_ptr unless C++03 compatibility is - required.
    -
    auto_ptr
    -
    Confusing and bug-prone ownership-transfer semantics. Use - unique_ptr instead, if possible.
    +

    + If dynamic allocation is necessary, prefer to keep ownership with + the code that allocated it. If other code needs access to the object, + consider passing it a copy, or passing a pointer or reference + without transferring ownership. Prefer to use + std::unique_ptr to make ownership transfer explicit. + For example: + + std::unique_ptr<Foo> FooFactory(); + void FooConsumer(std::unique_ptr<Foo> ptr); + -

    shared_ptr
    -
    - Safe with const referents (i.e. shared_ptr<const - T>). Reference-counted pointers with non-const referents - can occasionally be the best design, but try to rewrite with single - owners where possible. -
    -
    +

    +

    + Do not design your code to use shared ownership without a very good + reason. One such reason is to avoid expensive copy operations, + but you should only do this if the performance benefits are + significant, and the underlying object is immutable (i.e. + shared_ptr<const Foo>). If you do use shared + ownership, prefer to use shared_ptr. + +

    +

    + Do not use scoped_ptr in new code unless you need to be + compatible with older versions of C++. Never use + linked_ptr or std::auto_ptr. In all three + cases, use std::unique_ptr instead. +

    +
    @@ -1606,6 +1859,75 @@ Tashana Landray + + + Do not use rvalue references, std::forward, + std::move_iterator, or std::move_if_noexcept. + Use the single-argument form of std::move only with + non-copyable arguments. + + + + Rvalue references are a type of reference that can only bind to temporary + objects. The syntax is similar to traditional reference syntax. + For example, void f(string&& s); declares a + function whose argument is an rvalue reference to a string. + + +
      +
    • Defining a move constructor (a constructor taking an rvalue + reference to the class type) makes it possible to move a value instead + of copying it. If v1 is a vector<string>, + for example, then auto v2(std::move(v1)) will probably + just result in some simple pointer manipulation instead of copying a + large amount of data. In some cases this can result in a major + performance improvement. +
    • +
    • + Rvalue references make it possible to write a generic function + wrapper that forwards its arguments to another function, and works + whether or not its arguments are temporary objects. +
    • +
    • + Rvalue references make it possible to implement types that are + moveable but not copyable, which can be useful for types that have + no sensible definition of copying but where you might still want to + pass them as function arguments, put them in containers, etc. +
    • +
    • + std::move is necessary to make effective use of some + standard-library types, such as std::unique_ptr. +
    • +
    +
    + +
      +
    • Rvalue references are a relatively new feature (introduced as part + of C++11), and not yet widely understood. Rules like reference + collapsing, and automatic synthesis of move constructors, are + complicated. +
    • +
    • Rvalue references encourage a programming style that makes heavier + use of value semantics. This style is + unfamiliar to many developers, and its performance characteristics + can be hard to reason about. +
    • +
    +
    + +

    + Do not use rvalue references, and do not use the + std::forward or std::move_if_noexcept + utility functions (which are essentially just casts to rvalue + reference types), or std::move_iterator. Use + single-argument std::move only with objects that are + not copyable (e.g. std::unique_ptr), or in templated + code with objects that might not be copyable. +

    +
    + +
    + Use overloaded functions (including constructors) only if a @@ -1863,6 +2185,12 @@ Tashana Landray Things would probably be different if we had to do it all over again from scratch.

    +

    + This prohibition also applies to the exception-related + features added in C++11, such as noexcept, + std::exception_ptr, and + std::nested_exception. +

    There is an exception to this rule (no pun intended) for Windows code. @@ -2179,6 +2507,8 @@ Tashana Landray

    Use const whenever it makes sense. + With C++11, + constexpr is a better choice for some uses of const. @@ -2263,6 +2593,49 @@ Tashana Landray + + + In C++11, use constexpr + to define true constants or to ensure constant initialization. + + + + Some variables can be declared constexpr + to indicate the variables are true constants, + i.e. fixed at compilation/link time. + Some functions and constructors can be declared constexpr + which enables them to be used + in defining a constexpr variable. + + + Use of constexpr enables + definition of constants with floating-point expressions + rather than just literals; + definition of constants of user-defined types; and + definition of constants with function calls. + + + Prematurely marking something as constexpr + may cause migration problems if later on it has to be downgraded. + + Current restrictions on what is allowed + in constexpr functions and constructors + may invite obscure workarounds in these definitions. + + +

    + constexpr definitions enable a more robust + specification of the constant parts of an interface. + Use constexpr to specify true constants + and the functions that support their definitions. + Avoid complexifying function definitions to enable + their use with constexpr. + Do not use constexpr to force inlining. +

    +
    + +
    + Of the built-in C++ integer types, the only one used @@ -2448,13 +2821,15 @@ Tashana Landray %u %"PRIuS", %"PRIxS" - C99 specifies %zu + + C99 specifies %zu ptrdiff_t %d %"PRIdS" - C99 specifies %zd + + C99 specifies %td @@ -2587,8 +2962,8 @@ Tashana Landray

    - For pointers (address values), there is a choice between 0 - and NULL (and, for C++11, nullptr). + For pointers (address values), there is a choice between 0, + NULL, and nullptr. For projects that allow C++11 features, use nullptr. For C++03 projects, we prefer NULL because it looks like a pointer. In fact, some C++ compilers provide special definitions of @@ -2817,6 +3192,58 @@ Tashana Landray + +

    + Do not use lambda expressions, or the related std::function + or std::bind utilities. + + + + Lambda expressions are a concise way of creating anonymous function + objects. They're often useful when passing functions as arguments. + For example: std::sort(v.begin(), v.end(), + [](string x, string y) { return x[1] < y[1]; }); Lambdas were + introduced in C++11 along with a set of utilities for working with + function objects, such as the polymorphic wrapper + std::function. + + +
      +
    • + Lambdas are much more concise than other ways of defining function + objects to be passed to STL algorithms, which can be a readability + improvement. +
    • +
    • + Lambdas, std::function, and std::bind + can be used in combination as a general purpose callback + mechanism; they make it easy to write functions that take bound + functions as arguments. +
    • +
    +
    + +
      +
    • + Variable capture in lambdas can be tricky, and might be a new + source of dangling-pointer bugs. +
    • +
    • + It's possible for use of lambdas to get out of hand; very long + nested anonymous functions can make code harder to understand. +
    • + +
    +
    + +

    + Do not use lambda expressions, std::function or + std::bind. +

    +
    + + + Use only approved libraries from the Boost library collection. @@ -2880,6 +3307,11 @@ Tashana Landray
  • Bimap from boost/bimap
  • +
  • + Statistical Distributions and Functions from + boost/math/distributions +
  • + We are actively considering adding other Boost features to the list, so this list may be expanded in the future. @@ -2888,14 +3320,14 @@ Tashana Landray The following libraries are permitted, but their use is discouraged because they've been superseded by standard libraries in C++11: @@ -2908,11 +3340,12 @@ Tashana Landray - Use only approved libraries and language extensions from C++11 (formerly - known as C++0x). + Use libraries and language extensions from C++11 (formerly + known as C++0x) when appropriate. Consider portability to other environments before using C++11 features in your project. + @@ -2935,7 +3368,8 @@ Tashana Landray unfamiliar to many developers. The long-term effects of some features on code readability and maintenance are unknown. We cannot predict when its various features will be implemented uniformly by - tools that may be of interest (gcc, icc, clang, Eclipse, etc.). + tools that may be of interest, particularly in the case of projects + that are forced to use older versions of tools.

    As with Boost, some C++11 extensions encourage @@ -2946,108 +3380,47 @@ Tashana Landray mechanisms, which may lead to confusion and conversion costs.

    + - Use only C++11 libraries and language features that have been approved - for use. - Currently only the following C++11 features are approved: +

    + C++11 features may be used unless specified otherwise. In addition to + what's described in the rest of the style guide, the following C++11 + features may not be used: +

      -
    • auto (for local variables only).
    • - constexpr (for ensuring constants).
    • -
    • Use of >> with no intervening space to - close multiple levels of template arguments, as in - set<list<string>>, - where C++03 required a space as in - set<list<string> >. + Functions with trailing return types, e.g. writing + auto foo() -> int; instead of + int foo();, because of a desire to preserve + stylistic consistency with the many existing function + declarations. +
    • + + + + + +
    • + Compile-time rational numbers (<ratio>), + because of concerns that it's tied to a more template-heavy + interface style. +
    • +
    • + The <cfenv> and <fenv.h> + headers, because many compilers do not support those + features reliably. +
    • + +
    • + Lambda expressions, or the related std::function or + std::bind utilities.
    • -
    • Range-based - for loops.
    • -
    • Use of the LL and ULL suffixes on - numeric literals to guarantee that their type is at least 64 bits - wide.
    • -
    • Variadic macros (but note - that use of macros is discouraged).
    • -
    • All of the new STL algorithms in the - <algorithm> - and <numeric> - headers.
    • -
    • Use of local types as template parameters.
    • -
    • nullptr and nullptr_t.
    • -
    • static_assert.
    • -
    • Everything in <array>.
    • -
    • Everything in <tuple>. -
    • -
    • Variadic templates.
    • -
    • Alias templates (the new using syntax) may be used. - Don't use an alias declaration where a typedef will work.
    • -
    • unique_ptr, with restrictions (see - below).
    • -
    • Brace initialization syntax. See - the full section for more - detail.
    - Other features will be approved individually as appropriate. - Avoid writing code that is incompatible with C++11 (even though it - works in C++03). -
    - - - Use unique_ptr freely within classes and functions, - but do not use it to transfer ownership outside of a single .cc/.h - pair. - - - - unique_ptr is a "smart" pointer type which expresses - exclusive ownership of the underlying object. It provides "move - semantics", which enables it to be stored in containers and used - as a function parameter or return value, even though it cannot be - copied (to preserve the unique-ownership property). - - -
      -
    • It fully automates memory management of singly-owned pointers, - virtually eliminating the risk of leaking the underlying memory.
    • -
    • It provides a single, universal abstraction for singly-owned - pointers, replacing close to a dozen overlapping partial solutions - in common use at Google.
    • -
    • It can be passed into and returned from functions, providing - a self-documenting and compiler-enforced way to transfer ownership - between scopes.
    • -
    • Its performance is essentially identical to a plain pointer.
    • -
    -
    - -
      -
    • It cannot be used in code that requires C++03 compatibility.
    • -
    • Move semantics implicitly rely on rvalue references, - a new C++11 feature which is unfamiliar to many Googlers.
    • -
    • Google code currently uses a completely different set of - conventions for ownership transfer. Mixing unique_ptr - with the existing conventions could add complexity and create - confusion.
    • -
    • Best practices for using unique_ptr within Google - have not yet been established.
    • -
    -
    - -

    Use of unique_ptr as a class member or local variable - is encouraged, as is storing unique_ptr in containers - that support it. However, for the time being it is forbidden to use - unique_ptr as a function parameter or return value, - except for functions that are local to a single .cc/.h pair.

    -

    Note that the std::move() function, which is often - used to pass unique_ptr into function calls, remains - forbidden.

    -
    - -
    - @@ -3969,11 +4342,31 @@ Tashana Landray an encoding understood by most tools able to handle more than just ASCII. +

    +

    Hex encoding is also OK, and encouraged where it enhances - readability — for example, "\xEF\xBB\xBF" is the + readability — for example, "\xEF\xBB\xBF", + or, even more simply, u8"\uFEFF", is the Unicode zero-width no-break space character, which would be invisible if included in the source as straight UTF-8.

    +

    + Use the u8 prefix to guarantee + that a string literal containing \uXXXX escape + sequences is encoded as UTF-8. Do not use it for strings containing + non-ASCII characters encoded as UTF-8, because that will produce + incorrect output if the compiler does not interpret the source file + as UTF-8. + +

    +

    + You shouldn't use the C++11 char16_t and + char32_t character types, since they're for + non-UTF-8 text. For similar reasons you also shouldn't use + wchar_t (unless you're writing code that + interacts with the Windows API, which uses wchar_t + extensively). +

    @@ -4031,8 +4424,11 @@ Tashana Landray Some points to note:

      -
    • The return type is always on the same line as the - function name. +
    • If you cannot fit the return type and the function name on a single + line, break between them. +
    • +
    • If you break after the return type of a function definition, do not + indent.
    • The open parenthesis is always on the same line as the function name. @@ -4149,13 +4545,14 @@ Tashana Landray - On one line if it fits, otherwise wrap at the open brace. + Format a braced list exactly like you would format a function call in its + place.

      - Put everything on one line where possible. If everything can't fit - on one line, the open brace should be the last character on its line, - and the close brace should be the first character on its line. + If the braced list follows a name (e.g. a type or variable name), + format as if the {} were the parentheses of a function call + with that name. If there is no name, assume a zero-length name.

      // Examples of braced init list on a single line. @@ -4164,28 +4561,25 @@ Tashana Landray pair<int, int> p{foo, bar}; // When you have to wrap. - MyType m = { - superlongvariablename1, - superlongvariablename2, - {short, interior, list}, - { - interiorwrappinglist, - interiorwrappinglist2 - } - }; - - // Wrapping inside a function call. - function({ - wrapped, long, - list, here - }); - - // If the variable names are really long. - function( - { - wrapped, - list - }); + SomeFunction( + {"assume a zero-length name before {"}, + some_other_function_parameter); + SomeType variable{ + some, other, values, + {"assume a zero-length name before {"}, + SomeOtherType{ + "Very long string requiring the surrounding breaks.", + some, other values}, + SomeOtherType{"Slightly shorter string", + some, other, values}}; + SomeType variable{ + "This is too long to fit all in one line"}; + MyType m = { // Here, you could also break before {. + superlongvariablename1, + superlongvariablename2, + {short, interior, list}, + {interiorwrappinglist, + interiorwrappinglist2}};
      @@ -4947,7 +5341,7 @@ Tashana Landray

      -Revision 3.260 +Revision 3.274

      diff --git a/javascriptguide.xml b/javascriptguide.xml index a33c481..a80a032 100644 --- a/javascriptguide.xml +++ b/javascriptguide.xml @@ -3,7 +3,7 @@

      - Revision 2.82 + Revision 2.93

      @@ -78,7 +78,7 @@
    • Never use the const keyword - as it not supported in Internet Explorer.
    • + as it's not supported in Internet Explorer.
    @@ -112,8 +112,13 @@ lack of support in Internet Explorer).

    A @const annotation on a method additionally - implies that the method should not be overridden in subclasses. + implies that the method cannot not be overridden in subclasses.

    + +

    A @const annotation on a constructor implies the + class cannot be subclassed (akin to final in Java). +

    + @@ -139,7 +144,7 @@ overwritten.

    -

    The open source compiler will allow the symbol it to be +

    The open source compiler will allow the symbol to be overwritten because the constant is not marked as @const.

    @@ -151,6 +156,15 @@ MyClass.fetchedUrlCache_ = new goog.structs.Map(); + + /** + * Class that cannot be subclassed. + * @const + * @constructor + */ + sloth.MyFinalClass = function() {}; + +

    In this case, the pointer can never be overwritten, but value is highly mutable and not constant (and thus in camelCase, not ALL_CAPS).

    @@ -187,7 +201,7 @@ // 2. Trying to do one thing on Internet Explorer and another on Firefox. // I know you'd never write code like this, but throw me a bone. - [normalVersion, ffVersion][isIE](); + [ffVersion, ieVersion][isIE](); var THINGS_TO_EAT = [apples, oysters, sprayOnCheese] // No semicolon here. @@ -202,11 +216,12 @@ "called" resulting in an error.
  • You will most likely get a 'no such property in undefined' error at runtime as it tries to call - x[ffVersion][isIE]().
  • -
  • die is called unless - resultOfOperation() is NaN and - THINGS_TO_EAT gets assigned the result of - die().
  • + x[ffVersion, ieVersion][isIE](). +
  • die is always called since the array minus 1 is + NaN which is never equal to anything (not even if + resultOfOperation() returns NaN) and + THINGS_TO_EAT gets assigned the result of + die().
  • @@ -265,7 +280,7 @@ Expression to define a function within a block:

    if (x) { - var foo = function() {} + var foo = function() {}; } @@ -343,8 +358,7 @@ the Closure Library - or something similar. - + or a similar library function.

    function D() { @@ -420,8 +434,7 @@

    The ability to create closures is perhaps the most useful and often overlooked feature of JS. Here is - a good description of how closures work - .

    + a good description of how closures work.

    One thing to keep in mind, however, is that a closure keeps a pointer to its enclosing scope. As a result, attaching a closure to a DOM element can create a circular reference and thus, a memory leak. For @@ -443,7 +456,7 @@ } function bar(a, b) { - return function() { /* uses a and b */ } + return function() { /* uses a and b */ }; } @@ -451,53 +464,43 @@

    - Only for deserialization (e.g. evaluating RPC responses) + Only for code loaders and REPL (Read–eval–print loop)

    eval() makes for confusing semantics and is dangerous to use if the string being eval()'d contains user input. - There's usually a better, more clear, safer way to write your code, so - its use is generally not permitted. However eval makes - deserialization considerably easier than the non-eval - alternatives, so its use is acceptable for this task (for example, to - evaluate RPC responses).

    -

    Deserialization is the process of transforming a series of bytes into - an in-memory data structure. For example, you might write objects out - to a file as:

    + There's usually a better, clearer, and safer way to write your code, + so its use is generally not permitted.

    + +

    For RPC you can always use JSON and read the result using + JSON.parse() instead of eval().

    + +

    Let's assume we have a server that returns something like this:

    + - users = [ - { - name: 'Eric', - id: 37824, - email: 'jellyvore@myway.com' - }, - { - name: 'xtof', - id: 31337, - email: 'b4d455h4x0r@google.com' - }, - ... - ]; - -

    Reading these data back into memory is as simple as - evaling the string representation of the file.

    -

    Similarly, eval() can simplify decoding RPC return - values. For example, you might use an XMLHttpRequest - to make an RPC, and in its response the server can return - JavaScript:

    - - var userOnline = false; - var user = 'nusrat'; - var xmlhttp = new XMLHttpRequest(); - xmlhttp.open('GET', 'http://chat.google.com/isUserOnline?user=' + user, false); - xmlhttp.send(''); - // Server returns: - // userOnline = true; - if (xmlhttp.status == 200) { - eval(xmlhttp.responseText); + { + "name": "Alice", + "id": 31502, + "email": "looking_glass@example.com" } - // userOnline is now true. + + + var userInfo = eval(feed); + var email = userInfo['email']; + + +

    If the feed was modified to include malicious JavaScript code, then + if we use eval then that code will be executed.

    + + + var userInfo = JSON.parse(feed); + var email = userInfo['email']; + + +

    With JSON.parse, invalid JSON (including all executable + JavaScript) will cause an exception to be thrown.

    +
    @@ -768,7 +771,6 @@ * WRONG -- Do NOT do this. */ var foo = { get next() { return this.nextId++; } }; - }; @@ -1080,8 +1082,8 @@ // ... } - // Parenthesis-aligned, one argument per line. Visually groups and - // emphasizes each individual argument. + // Parenthesis-aligned, one argument per line. Emphasizes each + // individual argument. function bar(veryDescriptiveArgumentNumberOne, veryDescriptiveArgumentTwo, tableModelEventHandlerProxy, @@ -1184,13 +1186,14 @@ }); // goog.scope - -

    In fact, except for - - array and object initializers - , and passing anonymous functions, all wrapped lines - should be indented either left-aligned to the expression above, or - indented four spaces, not indented two spaces.

    + +

    Except for array literals, + object literals, and anonymous functions, all wrapped lines + should be indented either left-aligned to a sibling expression + above, or four spaces (not two spaces) deeper than a parent + expression (where "sibling" and "parent" refer to parenthesis + nesting level). +

    someWonderfulHtml = '
    ' + @@ -1202,8 +1205,13 @@ thisIsAVeryLongVariableName = hereIsAnEvenLongerOtherFunctionNameThatWillNotFitOnPrevLine(); - thisIsAVeryLongVariableName = 'expressionPartOne' + someMethodThatIsLong() + - thisIsAnEvenLongerOtherFunctionNameThatCannotBeIndentedMore(); + thisIsAVeryLongVariableName = siblingOne + siblingTwo + siblingThree + + siblingFour + siblingFive + siblingSix + siblingSeven + + moreSiblingExpressions + allAtTheSameIndentationLevel; + + thisIsAVeryLongVariableName = operandOne + operandTwo + operandThree + + operandFour + operandFive * ( + aNestedChildExpression + shouldBeIndentedMore); someValue = this.foo( shortArg, @@ -2208,8 +2216,7 @@

    We follow the - C++ style for comments - in spirit. + C++ style for comments in spirit.

    All files, classes, methods and properties should be documented with @@ -2229,9 +2236,8 @@

    The JSDoc syntax is based on - JavaDoc - . Many tools extract metadata from JSDoc comments to perform - code validation and optimizations. These comments must be + JavaDoc. Many tools extract metadata from JSDoc comments to + perform code validation and optimizations. These comments must be well-formed.

    @@ -2260,7 +2266,8 @@ }; -

    You should not indent the @fileoverview command.

    +

    You should not indent the @fileoverview command. You do not have to + indent the @desc command.

    Even though it is not preferred, it is also acceptable to line up the description.

    @@ -2476,14 +2483,14 @@ */ mynamespace.Request.prototype.initialize = function() { // This method cannot be overridden in a subclass. - } + };

    Marks a variable (or property) as read-only and suitable for inlining.

    -

    A @const variable is a immutable pointer to +

    A @const variable is an immutable pointer to a value. If a variable or property marked as @const is overwritten, JSCompiler will give warnings.

    @@ -2532,7 +2539,10 @@ /** @define {boolean} */ var TR_FLAGS_ENABLE_DEBUG = true; - /** @define {boolean} */ + /** + * @define {boolean} Whether we know at compile-time that + * the browser is IE. + */ goog.userAgent.ASSUME_IE = false; @@ -2902,6 +2912,27 @@ + + @nocompile + + @nocompile +

    For example:

    + + /** @nocompile */ + + // JavaScript code + + + + Used at the top of a file to tell the compiler to parse this + file but not compile it. + Code that is not meant for compilation and should be omitted + from compilation tests (such as bootstrap code) uses this + annotation. + Use sparingly. + + + @nosideeffects @@ -2911,7 +2942,7 @@ /** @nosideeffects */ function noSideEffectsFn1() { // ... - }; + } /** @nosideeffects */ var noSideEffectsFn2 = function() { @@ -2943,7 +2974,7 @@ * @return {string} Human-readable representation of project.SubClass. * @override */ - project.SubClass.prototype.toString() { + project.SubClass.prototype.toString = function() { // ... }; @@ -3000,9 +3031,7 @@ Used in conjunction with a trailing underscore on the method or property name to indicate that the member is - private. - Trailing underscores may eventually be deprecated as tools are - updated to enforce @private. + private and final. @@ -3014,8 +3043,7 @@

    For example:

    /** - * Sets the component's root element to the given element. Considered - * protected and final. + * Sets the component's root element to the given element. * @param {Element} element Root element for the component. * @protected */ @@ -3032,6 +3060,30 @@ + + @public + + @public
    + @public {type} +

    For example:

    + + /** + * Whether to cancel the event in internal capture/bubble processing. + * @public {boolean} + * @suppress {visiblity} Referencing this outside this package is strongly + * discouraged. + */ + goog.events.Event.prototype.propagationStopped_ = false; + + + + Used to indicate that the member or property is public. Variables and + properties are public by default, so this annotation is rarely necessary. + Should only be used in legacy code that cannot be easily changed to + override the visibility of members that were named as private variables. + + + @return @@ -3136,6 +3188,9 @@ @suppress {warning1|warning2} + + @suppress {warning1,warning2} +

    For example:

    /** @@ -3148,7 +3203,7 @@ Suppresses warnings from tools. Warning categories are - separated by |. + separated by | or ,. @@ -3166,7 +3221,7 @@ * @template T */ goog.bind = function(fn, thisObj, var_args) { - ... + ... }; @@ -3413,7 +3468,7 @@

    Instead of this:

    - if (val != 0) { + if (val) { return foo(); } else { return bar(); @@ -3557,7 +3612,7 @@

    - Revision 2.82 + Revision 2.93

    diff --git a/lispguide.xml b/lispguide.xml index f566315..0a5684b 100644 --- a/lispguide.xml +++ b/lispguide.xml @@ -5,7 +5,7 @@

    -Revision 1.22 +Revision 1.23

    @@ -74,7 +74,8 @@ Robert Brown Practical Common Lisp. For a language reference, please consult the Common Lisp HyperSpec. - For more detailed style guidance, take a look at Peter Norvig and Kent Pitman's + For more detailed style guidance, take (with a pinch of salt) + a look at Peter Norvig and Kent Pitman's style guide.

    @@ -2707,7 +2708,7 @@ Robert Brown instead of FIRST and REST also makes sense. However, keep in mind that it might be more appropriate in such cases to use higher-level constructs such as - DESTRUCTURING-BIND or FARE-MATCHER:MATCH. + DESTRUCTURING-BIND or OPTIMA:MATCH.

    @@ -3348,12 +3349,12 @@ Robert Brown

    - DYNAMIC-EXTENT declaration are + DYNAMIC-EXTENT declarations are a particular case of unsafe operations.

    - The purpose of the DYNAMIC-EXTENT declaration + The purpose of a DYNAMIC-EXTENT declaration is to improve performance by reducing garbage collection in cases where it appears to be obvious that an object's lifetime is within the "dynamic extent" of a function. @@ -3380,7 +3381,7 @@ Robert Brown The lists created to store &REST parameters.

  • - Lists and vector allocated within a function. + Lists, vectors and structures allocated within a function.
  • Closures. @@ -3390,8 +3391,8 @@ Robert Brown If the assertion is wrong, i.e. if the programmer's claim is not true, the results can be catastrophic: Lisp can terminate any time after the function returns, - or it hang forever, or — worst of all — - produce incorrect results without any runtime error! + or it can hang forever, or — worst of all — + it can produce incorrect results without any runtime error!

    Even if the assertion is correct, @@ -3433,18 +3434,19 @@ Robert Brown by analyzing where the function is called and what other functions it is passed to; therefore, you should somewhat wary of declaring a function - DYNAMIC-EXTENT, but not a high-stress declaration. + DYNAMIC-EXTENT, but this is not a high-stress declaration. On the other hand, it is much harder to ascertain that none of the objects ever bound or assigned to that variable + and none of their sub-objects will escape the dynamic extent of the current call frame, - nor will in any future modification of a function. + and that they still won't in any future modification of a function. Therefore, you should be extremely wary of declaring a variable DYNAMIC-EXTENT.

    - It's sometimes hard to know what the rate will be. + It's usually hard to predict the effect of such optimization on performance. When writing a function or macro - that's part of a library of reusable code, + that is part of a library of reusable code, there's no a priori way to know how often the code will run. Ideally, tools would be available to discover the availability and suitability of using such an optimization @@ -3452,7 +3454,8 @@ Robert Brown in practice this isn't as easy as it ought to be. It's a tradeoff. If you're very, very sure that the assertion is true - (that the object is only used within the dynamic scope), + (that any object bound to the variable and any of its sub-objects + are only used within the dynamic extent of the specified scope), and it's not obvious how much time will be saved and it's not easy to measure, then it may be better to put in the declaration than to leave it out. @@ -3474,11 +3477,16 @@ Robert Brown otherwise guarantees the same semantics. Of course, you must use APPLY if it does what you want and REDUCE doesn't. + For instance:

    -

    - For instance, (apply #'+ (mapcar #'acc frobs) - should instead be (reduce #'+ frobs :key #'acc) -

    + + ;; Bad + (apply #'+ (mapcar #'acc frobs)) + + + ;; Better + (reduce #'+ frobs :key #'acc :initial-value 0) +

    This is preferable because it does not do extra consing, and does not risk going beyond CALL-ARGUMENTS-LIMIT @@ -3495,7 +3503,9 @@ Robert Brown Moreover, (REDUCE 'APPEND ...) is also O(n^2) unless you specify :FROM-END T. In such cases, you MUST NOT use REDUCE, - but instead you MUST use proper abstractions + and you MUST NOT use (APPLY 'STRCAT ...) + or (APPLY 'APPEND ...) either. + Instead you MUST use proper abstractions from a suitable library (that you may have to contribute to) that properly handles those cases without burdening users with implementation details. @@ -3508,7 +3518,7 @@ Robert Brown

    You should not use NCONC; you should use APPEND instead, - or better data structures. + or better, better data structures.

    @@ -3548,7 +3558,7 @@ Robert Brown (see Okasaki's book, and add them to lisp-interface-library), or more simply you should be accumulating data in a tree that will get flattened once in linear time - after the accumulation phase is complete (see how ASDF does it). + after the accumulation phase is complete.

    You may only use NCONC, MAPCAN @@ -3639,9 +3649,9 @@ Robert Brown

    ASDF 3 comes with a portability library UIOP - that makes it much easier to deal with pathnames - portably — and correctly — in Common Lisp. - You should use it when appropriate. + that makes it much easier to deal with pathnames + portably — and correctly — in Common Lisp. + You should use it when appropriate.

    First, be aware of the discrepancies between @@ -3695,7 +3705,7 @@ Robert Brown You should use other pathname abstractions, such as ASDF:SYSTEM-RELATIVE-PATHNAME or the underlying UIOP:SUBPATHNAME and - UIOP:PARSE-UNIX-NAMESTRING. + UIOP:PARSE-UNIX-NAMESTRING.

    @@ -3707,9 +3717,9 @@ Robert Brown reinitialize any search path from current environment variables. ASDF for instance requires you to reset its paths with ASDF:CLEAR-CONFIGURATION. - UIOP provides hooks - to call functions before an image is dumped, - from which to reset or makunbound relevant variables. + UIOP provides hooks + to call functions before an image is dumped, + from which to reset or makunbound relevant variables.

    @@ -3754,7 +3764,8 @@ Robert Brown

    That is why any function specified in a SATISFIES clause MUST accept objects of any type as argument to the function, - and MUST be defined within an EVAL-WHEN. + and MUST be defined within an EVAL-WHEN + (as well as any variable it uses or function it calls):

    (defun prime-number-p (n) ; Doubly bad! @@ -3829,7 +3840,7 @@ Robert Brown

    -Revision 1.22 +Revision 1.23

    diff --git a/objcguide.xml b/objcguide.xml index 73fcecd..68b6209 100644 --- a/objcguide.xml +++ b/objcguide.xml @@ -4,7 +4,7 @@

    -Revision 2.56 +Revision 2.59

    @@ -132,24 +132,20 @@ Revision 2.56 #import <Foundation/Foundation.h> // A sample class demonstrating good Objective-C style. All interfaces, - // categories, and protocols (read: all top-level declarations in a header) - // MUST be commented. Comments must also be adjacent to the object they're - // documenting. + // categories, and protocols (read: all non-trivial top-level declarations + // in a header) MUST be commented. Comments must also be adjacent to the + // object they're documenting. // // (no blank line between this comment and the interface) - @interface Foo : NSObject { - @private - NSString *_bar; - NSString *_bam; - } + @interface Foo : NSObject // Returns an autoreleased instance of Foo. See -initWithBar: for details // about |bar|. - + (id)fooWithBar:(NSString *)bar; + + (instancetype)fooWithBar:(NSString *)bar; // Designated initializer. |bar| is a thing that represents a thing that // does a thing. - - (id)initWithBar:(NSString *)bar; + - (instancetype)initWithBar:(NSString *)bar; // Gets and sets |_bar|. - (NSString *)bar; @@ -173,18 +169,21 @@ Revision 2.56 #import "Foo.h" - @implementation Foo + @implementation Foo { + NSString *_bar; + NSString *_foo; + } - + (id)fooWithBar:(NSString *)bar { + + (instancetype)fooWithBar:(NSString *)bar { return [[[self alloc] initWithBar:bar] autorelease]; } // Must always override super's designated initializer. - - (id)init { + - (instancetype)init { return [self initWithBar:nil]; } - - (id)initWithBar:(NSString *)bar { + - (instancetype)initWithBar:(NSString *)bar { if ((self = [super init])) { _bar = [bar copy]; _bam = [[NSString alloc] initWithFormat:@"hi %d", 3]; @@ -246,29 +245,14 @@ Revision 2.56 - Each line of text in your code should try to be at most 80 characters - long. + The maximum line length for Objective-C and Objective-C++ files is 100 + columns. Projects may opt to use an 80 column limit for consistency with + the C++ style guide.

    - Strive to keep your code within 80 columns. We realize that Objective C - is a verbose language and in some cases it may be more readable to - extend slightly beyond 80 columns, but this should definitely be the - exception and not commonplace. -

    -

    - If a reviewer asks that you reformat a line because they feel it can be - fit in 80 columns and still be readable, you should do so. -

    - -

    - We recognize that this rule is controversial, but so much existing - code already adheres to it, and we feel that consistency is - important. -

    -

    - You can make violations easier to spot in Xcode by going to Xcode - > Preferences > Text Editing > Show page guide. + You can make violations easier to spot by enabling Preferences > + Text Editing > Page guide at column: 100 in Xcode.

    @@ -445,9 +429,7 @@ Revision 2.56 - Blocks are preferred to the target-selector pattern when creating - callbacks, as it makes code easier to read. Code inside blocks should be - indented four spaces. + Code inside blocks should be indented four spaces.

    @@ -743,7 +725,7 @@ Revision 2.56 - (void)respondToSomething:(id)something { // bridge from Cocoa through our C++ backend _instanceVar = _backEndObject->DoSomethingPlatformSpecific(); - NSString* tempString = [NSString stringWithInt:_instanceVar]; + NSString* tempString = [NSString stringWithFormat:@"%d", _instanceVar]; NSLog(@"%@", tempString); } @end @@ -751,7 +733,7 @@ Revision 2.56 // The platform-specific implementation of the C++ class, using // C++ naming. int CrossPlatformAPI::DoSomethingPlatformSpecific() { - NSString* temp_string = [NSString stringWithInt:an_instance_var_]; + NSString* temp_string = [NSString stringWithFormat:@"%d", an_instance_var_]; NSLog(@"%@", temp_string); return [temp_string intValue]; } @@ -766,11 +748,10 @@ Revision 2.56

  • - In application-level code, prefixes on class names should - generally be avoided. Having every single class with same prefix - impairs readability for no benefit. When designing code to be shared - across multiple applications, prefixes are acceptable and recommended - (e.g. GTMSendMessage). + When designing code to be shared across multiple applications, + prefixes are acceptable and recommended (e.g. GTMSendMessage). + Prefixes are also recommended for classes of large applications that + depend on external libraries.

    @@ -1038,31 +1019,25 @@ Revision 2.56

    Where instance variables are pointers to Core Foundation, C++, and other non-Objective-C objects, they should always be declared with - the __strong or __weak type modifiers to indicate which pointers are - and are not retained. Core Foundation and other non-Objective-C object - pointers require explicit memory management, even when building for - automatic reference counting or garbage collection. When the __weak - type modifier is not allowed (e.g. C++ member variables when compiled - under clang), a comment should be used instead. -

    -

    - Be mindful that support for automatic C++ objects encapsulated in - Objective-C objects is disabled by default, as described - here. + strong and weak comments to indicate which + pointers are and are not retained. Core Foundation and other + non-Objective-C object pointers require explicit memory management, + even when building for automatic reference counting or garbage + collection.

    Examples of strong and weak declarations: @interface MyDelegate : NSObject { @private - IBOutlet NSButton *_okButton; // normal NSControl; implicitly weak on Mac only + IBOutlet NSButton *_okButton; // Normal NSControl; implicitly weak on Mac only - AnObjcObject* _doohickey; // my doohickey - __weak MyObjcParent *_parent; // so we can send msgs back (owns me) + AnObjcObject* _doohickey; // My doohickey + __weak MyObjcParent *_parent; // So we can send msgs back (owns me) // non-NSObject pointers... - __strong CWackyCPPClass *_wacky; // some cross-platform object - __strong CFDictionaryRef *_dict; + CWackyCPPClass *_wacky; // Strong, some cross-platform object + CFDictionaryRef *_dict; // Strong } @property(strong, nonatomic) NSString *doohickey; @property(weak, nonatomic) NSString *parent; @@ -1085,8 +1060,9 @@ Revision 2.56

    - Instance variables should be marked @private when they are - declared in a header file. + Instance variables should typically be declared in implementation files + or auto-synthesized by properties. When ivars are declared in a header + file, they should be marked @private. @@ -1094,9 +1070,6 @@ Revision 2.56 @private id _myInstanceVariable; } - // public accessors, setter takes ownership - - (id)myInstanceVariable; - - (void)setMyInstanceVariable:(id)theVar; @end @@ -1139,11 +1112,16 @@ Revision 2.56 @implementation.
    - This commonly applies (but is not limited) to the init..., - copyWithZone:, and dealloc methods. - init... methods should be grouped together, followed by - the copyWithZone: method, and finally the - dealloc method. +

    + This commonly applies (but is not limited) to the init..., + copyWithZone:, and dealloc methods. + init... methods should be grouped together, followed by + other NSObject methods. +

    +

    + Convenience class methods for creating instances may precede the + NSObject methods. +

    @@ -1201,7 +1179,7 @@ Revision 2.56 - (NSString *)doSomethingWithDelegate; // Declare private method @end - @implementation GTMFoo(PrivateDelegateHandling) + @implementation GTMFoo (PrivateDelegateHandling) ... - (NSString *)doSomethingWithDelegate { // Implement this method @@ -1209,14 +1187,6 @@ Revision 2.56 ... @end -

    - Before Objective-C 2.0, if you declare a method in the private - @interface, but forget to implement it in the main - @implementation, the compiler will not object. - (This is because you don't implement these private methods in a - separate category.) The solution is to put the functions within - an @implementation that specifies the category. -

    If you are using Objective-C 2.0, you should instead declare your private category using a class @@ -1387,7 +1357,7 @@ Revision 2.56 accessors.

    - - (id)init { + - (instancetype)init { self = [super init]; if (self) { _bar = [[NSMutableString alloc] init]; // good @@ -1401,7 +1371,7 @@ Revision 2.56 } - - (id)init { + - (instancetype)init { self = [super init]; if (self) { self.bar = [NSMutableString string]; // avoid @@ -1475,62 +1445,6 @@ Revision 2.56 you do use them please document exactly which methods you expect to throw.

    -

    - Do not use the NS_DURING, NS_HANDLER, - NS_ENDHANDLER, NS_VALUERETURN and - NS_VOIDRETURN macros unless you are writing code that - needs to run on Mac OS X 10.2 or before. -

    -

    - Also be aware when writing Objective-C++ code that stack based objects - are not cleaned up when you throw an Objective-C exception. - Example: -

    - - class exceptiontest { - public: - exceptiontest() { NSLog(@"Created"); } - ~exceptiontest() { NSLog(@"Destroyed"); } - }; - - void foo() { - exceptiontest a; - NSException *exception = [NSException exceptionWithName:@"foo" - reason:@"bar" - userInfo:nil]; - @throw exception; - } - - int main(int argc, char *argv[]) { - GMAutoreleasePool pool; - @try { - foo(); - } - @catch(NSException *ex) { - NSLog(@"exception raised"); - } - return 0; - } - -

    - will give you: -

    - - 2006-09-28 12:34:29.244 exceptiontest[23661] Created - 2006-09-28 12:34:29.244 exceptiontest[23661] exception raised - -

    - Note that the destructor for a never got called. This is a - major concern for stack based smartptrs such as - shared_ptr and linked_ptr, as well as any - STL objects that you may want to use. Therefore it pains us to say - that if you must use exceptions in your Objective-C++ code, use C++ - exceptions whenever possible. You should never re-throw an Objective-C - exception, nor are stack based C++ objects (such as - std::string, std::vector etc.) allowed in - the body of any @try, @catch, or - @finally blocks. -

    @@ -1541,19 +1455,24 @@ Revision 2.56

    - Use nil checks for logic flow of the application, not for - crash prevention. Sending a message to a nil object is - handled by the Objective-C runtime. If the method has no return - result, you're good to go. However if there is one, there may be - differences based on runtime architecture, return size, and OS X - version (see Apple's - documentation for specifics). + Use nil pointer checks for logic flow of the application, + not for preventing crashes when sending messages. With current compilers + ( + as of LLVM 3.0/Xcode 4.2), sending a message to nil + reliably returns nil as a pointer, zero as an integer or floating-point + value, structs initialized to 0, and _Complex values equal + to {0, 0}.

    - Note that this is very different from checking C/C++ pointers against - NULL, which the runtime does not handle and will cause - your application to crash. You still need to make sure you do not - dereference a NULL pointer. + Note that this applies to nil as a message target, not as + a parameter value. Individual methods may or may not safely handle + nil parameter values. +

    +

    + Note too that this is distinct from checking C/C++ pointers and block + pointers against NULL, which the runtime does not handle + and will cause your application to crash. You still need to make sure + you do not dereference a NULL pointer.

    @@ -1677,7 +1596,7 @@ Revision 2.56 @implementation MyClass @synthesize name = _name; - - (id)init { + - (instancetype)init { ... } @end @@ -1867,11 +1786,12 @@ Revision 2.56 - Delegate objects should not be retained. + Delegate objects should not be retained when doing so would create + a retain cycle.

    - A class that implements the delegate pattern should: + A class that implements the delegate pattern should typically:

    1. Have an instance variable named _delegate to reference @@ -1882,7 +1802,9 @@ Revision 2.56 and setDelegate:.
    2. - The _delegate object should not be retained. + The _delegate object should be weak if the class + is typically retained by its delegate, such that a strong delegate + would create a retain cycle.

    @@ -1915,8 +1837,6 @@ Revision 2.56
  • Define callback APIs with @protocol, using @optional if not all the methods are required. - (Exception: when using Objective-C 1.0, @optional isn't - available, so use a category to define an "informal protocol".)
  • @@ -1951,7 +1871,7 @@ Revision 2.56

    -Revision 2.56 +Revision 2.59

    diff --git a/pyguide.html b/pyguide.html index 31fc512..632c9c6 100644 --- a/pyguide.html +++ b/pyguide.html @@ -136,7 +136,7 @@

    Google Python Style Guide

    - Revision 2.54 + Revision 2.59

    @@ -165,7 +165,7 @@ +Lint Imports Packages Exceptions Global variables Nested/Local/Inner Classes and Functions List Comprehensions Default Iterators and Operators Generators Lambda Functions Conditional Expressions Default Argument Values Properties True/False evaluations Deprecated Language Features Lexical Scoping Function and Method Decorators Threading Power Features @@ -214,58 +214,77 @@

    Python Language Rules

    - -
    -

    pychecker

    - +
    +

    Lint

    + link - +
    - Run pychecker over your code. + Run pylint over your code.
    -
    @@ -358,7 +372,6 @@

    Decision: All new code should import each module by its full package name. -

    Imports should be as follows: @@ -784,6 +797,10 @@ from sound.effects import echo if b is None: b = []

    No:  def foo(a, b=[]):
    +         ...
    +No:  def foo(a, b=time.time()):  # The time the module was loaded???
    +         ...
    +No:  def foo(a, b=FLAGS.my_thing):  # sys.argv has not yet been parsed...
              ...

    @@ -1134,7 +1151,7 @@ from sound.effects import echo Avoid external dependencies in the decorator itself (e.g. don't rely on files, sockets, database connections, etc.), since they might not be available when the decorator runs (at import time, perhaps from - pychecker or other tools). A decorator that is + pydoc or other tools). A decorator that is called with valid parameters should (as much as possible) be guaranteed to succeed in all cases.

    @@ -1347,10 +1364,24 @@ from sound.effects import echo foo = long_function_name(var_one, var_two, var_three, var_four) + # Aligned with opening delimiter in a dictionary + foo = { + long_dictionary_key: value1 + + value2, + ... + } + # 4-space hanging indent; nothing on first line foo = long_function_name( var_one, var_two, var_three, - var_four) + var_four) + + # 4-space hanging indent in a dictionary + foo = { + long_dictionary_key: + long_dictionary_value, + ... + }
    No:    # Stuff on first line forbidden
            foo = long_function_name(var_one, var_two,
                var_three, var_four)
    @@ -1358,7 +1389,14 @@ from sound.effects import echo
            # 2-space hanging indent forbidden
            foo = long_function_name(
              var_one, var_two, var_three,
    -         var_four)
    + var_four) + + # No hanging indent in a dictionary + foo = { + long_dictionary_key: + long_dictionary_value, + ... + }
    @@ -1502,9 +1540,10 @@ from sound.effects import echo module, class or function. These strings can be extracted automatically through the __doc__ member of the object and are used by pydoc. (Try running - pydoc on your module to see how it looks.) Our - convention for doc strings is to use the three double-quote - format for strings. A doc string should be organized as a + pydoc on your module to see how it looks.) We + always use the three double-quote """ format for doc strings + (per PEP 257). + A doc string should be organized as a summary line (one physical line) terminated by a period, question mark, or exclamation point, followed by a blank line, followed by the rest of the doc string starting at the same @@ -1784,8 +1823,29 @@ from sound.effects import echo employee_table += '</table>'

    - Use """ for multi-line strings rather than - '''. Note, however, that it is often cleaner to + Be consistent with your choice of string quote character within a file. + Pick ' or " and stick with it. + It is okay to use the other quote character on a string to avoid the + need to \ escape within the string. + GPyLint enforces this. +

    + +
    Yes:
    +  Python('Why are you hiding your eyes?')
    +  Gollum("I'm scared of lint errors.")
    +  Narrator('"Good!" thought a happy Python reviewer.')
    +
    No:
    +  Python("Why are you hiding your eyes?")
    +  Gollum('The lint. It burns. It burns us.')
    +  Gollum("Always the great lint. Watching. Watching.")
    + +

    + Prefer """ for multi-line strings rather than + '''. Projects may choose to use ''' for + all non-docstring multi-line strings if and only if they also use + ' for regular strings. + Doc strings must use """ regardless. + Note that it is often cleaner to use implicit line joining since multi-line strings do not flow with the indentation of the rest of the program:

    @@ -2174,7 +2234,7 @@ Don't do this.
    @@ -2233,7 +2293,7 @@ Don't do this.

    -Revision 2.54 +Revision 2.59

    @@ -2241,9 +2301,11 @@ Revision 2.54 Amit Patel
    Antoine Picard
    Eugene Jhong
    + Gregory P. Smith
    Jeremy Hylton
    Matt Smart
    Mike Shields
    + Shane Liebling
    diff --git a/shell.xml b/shell.xml index 1735ed7..2e75857 100644 --- a/shell.xml +++ b/shell.xml @@ -4,7 +4,7 @@

    -Revision 1.25 +Revision 1.26

    @@ -393,6 +393,73 @@ Revision 1.25
    + + +
      +
    • + Indent alternatives by 2 spaces. +
    • +
    • + A one-line alternative needs a space after the close parenthesis of + the pattern and before the ;;. +
    • +
    • + Long or multi-command alternatives should be split over multiple + lines with the pattern, actions, and ;; on separate + lines. +
    • +
    +
    + +

    + The matching expressions are indented one level from the 'case' and + 'esac'. Multiline actions are indented another level. In general, + there is no need to quote match expressions. Pattern expressions + should not be preceded by an open parenthesis. Avoid the + ;& and ;;& notations. +

    + + case "${expression}" in + a) + variable="..." + some_command "${variable}" "${other_expr}" ... + ;; + absolute) + actions="relative" + another_command "${actions}" "${other_expr}" ... + ;; + *) + error "Unexpected expression '${expression}'" + ;; + esac + +

    + Simple commands may be put on the same line as the pattern and + ;; as long as the expression remains readable. This is + often appropriate for single-letter option processing. When the + actions don't fit on a single line, put the pattern on a line on its + own, then the actions, then ;; also on a line of its own. + When on the same line as the actions, use a space after the close + parenthesis of the pattern and another before the ;;. +

    + + verbose='false' + aflag='' + bflag='' + files='' + while getopts 'abf:v' flag; do + case "${flag}" in + a) aflag='true' ;; + b) bflag='true' ;; + f) files="${OPTARG}" ;; + v) verbose='true' ;; + *) error "Unexpected option ${flag}" ;; + esac + done + + +
    + In order of precedence: Stay consistent with what you find; @@ -856,9 +923,7 @@ Revision 1.25 VERBOSE='false' while getopts 'v' flag; do case "${flag}" in - 'v') - VERBOSE='true' - ;; + v) VERBOSE='true' ;; esac done readonly VERBOSE @@ -1081,7 +1146,7 @@ Revision 1.25

    -Revision 1.25 +Revision 1.26