mirror of
https://github.com/google/styleguide.git
synced 2024-03-22 13:11:43 +08:00
Merge pull request #650 from zetafunction/new-thingie
Update the C++ style guide.
This commit is contained in:
commit
9806df89a3
262
cppguide.html
262
cppguide.html
|
@ -165,7 +165,8 @@ input.</p>
|
|||
<h2 id="C++_Version">C++ Version</h2>
|
||||
|
||||
<p>Currently, code should target C++17, i.e., should not use C++2x
|
||||
features. The C++ version targeted by this guide will advance
|
||||
features, with the exception of <a href="#Designated_initializers">designated
|
||||
initializers</a>. The C++ version targeted by this guide will advance
|
||||
(aggressively) over time.</p>
|
||||
|
||||
|
||||
|
@ -441,6 +442,8 @@ as follows:</p>
|
|||
|
||||
<div>
|
||||
<li>Other libraries' <code>.h</code> files.</li>
|
||||
|
||||
<li>A blank line</li>
|
||||
</div>
|
||||
|
||||
<li>
|
||||
|
@ -957,10 +960,12 @@ does not make an observable difference. For example:</p>
|
|||
<h4>Common patterns</h4>
|
||||
|
||||
<ul>
|
||||
<li>Global strings: if you require a global or static string constant,
|
||||
consider using a simple character array, or a char pointer to the first
|
||||
element of a string literal. String literals have static storage duration
|
||||
already and are usually sufficient.</li>
|
||||
<li>Global strings: if you require a named global or static string constant,
|
||||
consider using a <code>constexpr</code> variable of
|
||||
<code>string_view</code>, character array, or character pointer, pointing
|
||||
to a string literal. String literals have static storage duration already
|
||||
and are usually sufficient.
|
||||
See <a href="https://abseil.io/tips/140">TotW #140.</a></li>
|
||||
<li>Maps, sets, and other dynamic containers: if you require a static, fixed
|
||||
collection, such as a set to search against or a lookup table, you cannot
|
||||
use the dynamic containers from the standard library as a static variable,
|
||||
|
@ -1003,7 +1008,7 @@ attribute. Prefer
|
|||
<code>thread_local</code> over other ways of defining thread-local data.</p>
|
||||
|
||||
<p class="definition"></p>
|
||||
<p>Starting with C++11, variables can be declared with the
|
||||
<p>Variables can be declared with the
|
||||
<code>thread_local</code> specifier:</p>
|
||||
<pre>thread_local Foo foo = ...;
|
||||
</pre>
|
||||
|
@ -1022,8 +1027,8 @@ thread, rather than once at program startup. This means that
|
|||
other <code>thread_local</code> variables are subject to the same
|
||||
initialization-order issues as static variables (and more besides).</p>
|
||||
|
||||
<p><code>thread_local</code> variable instances are destroyed when their thread
|
||||
terminates, so they do not have the destruction-order issues of static
|
||||
<p><code>thread_local</code> variable instances are not destroyed before their
|
||||
thread terminates, so they do not have the destruction-order issues of static
|
||||
variables.</p>
|
||||
|
||||
<p class="pros"></p>
|
||||
|
@ -1045,9 +1050,10 @@ variables.</p>
|
|||
<li>The memory consumed by a <code>thread_local</code> variable scales with
|
||||
the number of running threads (in the worst case), which can be quite large
|
||||
in a program.</li>
|
||||
<li>An ordinary class member cannot be <code>thread_local</code>.</li>
|
||||
<li>Non-static data members cannot be <code>thread_local</code>.</li>
|
||||
<li><code>thread_local</code> may not be as efficient as certain compiler
|
||||
intrinsics.</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<p class="decision"></p>
|
||||
|
@ -1164,10 +1170,10 @@ type is defined by a constructor that can take the source type as
|
|||
its only argument (or only argument with no default value).</p>
|
||||
|
||||
<p>The <code>explicit</code> keyword can be applied to a constructor
|
||||
or (since C++11) a conversion operator, to ensure that it can only be
|
||||
or a conversion operator, to ensure that it can only be
|
||||
used when the destination type is explicit at the point of use,
|
||||
e.g., with a cast. This applies not only to implicit conversions, but to
|
||||
C++11's list initialization syntax:</p>
|
||||
list initialization syntax:</p>
|
||||
<pre>class Foo {
|
||||
explicit Foo(int x, double y);
|
||||
...
|
||||
|
@ -1395,13 +1401,10 @@ recommended that you design your class so that the default implementation of
|
|||
those operations is correct. Remember to review the correctness of any
|
||||
defaulted operations as you would any other code.</p>
|
||||
|
||||
<p>Due to the risk of slicing, prefer to avoid providing a public assignment
|
||||
operator or copy/move constructor for a class that's
|
||||
intended to be derived from (and prefer to avoid deriving from a class
|
||||
with such members). If your base class needs to be
|
||||
copyable, provide a public virtual <code>Clone()</code>
|
||||
method, and a protected copy constructor that derived classes
|
||||
can use to implement it.</p>
|
||||
<p>To eliminate the risk of slicing, prefer to make base classes abstract,
|
||||
by making their constructors protected, by declaring their destructors protected,
|
||||
or by giving them one or more pure virtual member functions. Prefer to avoid
|
||||
deriving from concrete classes.</p>
|
||||
|
||||
|
||||
|
||||
|
@ -1505,7 +1508,9 @@ which are prone to ambiguity, confusion, and outright bugs.</p>
|
|||
|
||||
<p>All inheritance should be <code>public</code>. If you
|
||||
want to do private inheritance, you should be including
|
||||
an instance of the base class as a member instead.</p>
|
||||
an instance of the base class as a member instead. You may use
|
||||
<code>final</code> on classes when you don't intend to support using
|
||||
them as base classes.</p>
|
||||
|
||||
<p>Do not overuse implementation inheritance. Composition
|
||||
is often more appropriate. Try to restrict use of
|
||||
|
@ -1700,10 +1705,11 @@ sections that would be empty.</p>
|
|||
|
||||
<p>Within each section, prefer grouping similar
|
||||
kinds of declarations together, and prefer the
|
||||
following order: types (including <code>typedef</code>,
|
||||
<code>using</code>, <code>enum</code>, and nested structs and classes),
|
||||
constants, factory functions, constructors and assignment
|
||||
operators, destructor, all other methods, data members.</p>
|
||||
following order: types and type aliases (<code>typedef</code>,
|
||||
<code>using</code>, <code>enum</code>, nested structs and classes),
|
||||
static constants, factory functions, constructors and assignment
|
||||
operators, destructor, all other member and <code>friend</code> functions,
|
||||
data members.</p>
|
||||
|
||||
<p>Do not put large method definitions inline in the
|
||||
class definition. Usually, only trivial or
|
||||
|
@ -1731,7 +1737,7 @@ Avoid returning a pointer unless it can be null.</p>
|
|||
function, or both. Non-optional input parameters should usually be values
|
||||
or <code>const</code> references, while non-optional output and
|
||||
input/output parameters should usually be references (which cannot be null).
|
||||
Generally, use <code>absl::optional</code> to represent optional by-value
|
||||
Generally, use <code>std::optional</code> to represent optional by-value
|
||||
inputs, and use a <code>const</code> pointer when the non-optional form would
|
||||
have used a reference. Use non-<code>const</code> pointers to represent
|
||||
optional outputs and optional input/output parameters.</p>
|
||||
|
@ -1890,7 +1896,7 @@ doubt, use overloads.</p>
|
|||
form, the return type appears before the function name. For example:</p>
|
||||
<pre>int foo(int x);
|
||||
</pre>
|
||||
<p>The newer form, introduced in C++11, uses the <code>auto</code>
|
||||
<p>The newer form uses the <code>auto</code>
|
||||
keyword before the function name and a trailing return type after
|
||||
the argument list. For example, the declaration above could
|
||||
equivalently be written:</p>
|
||||
|
@ -1976,7 +1982,7 @@ can be used to automate ownership bookkeeping, to ensure
|
|||
these responsibilities are met.
|
||||
<a href="http://en.cppreference.com/w/cpp/memory/unique_ptr">
|
||||
<code>std::unique_ptr</code></a> is a smart pointer type
|
||||
introduced in C++11, which expresses exclusive ownership
|
||||
which expresses exclusive ownership
|
||||
of a dynamically allocated object; the object is deleted
|
||||
when the <code>std::unique_ptr</code> goes out of scope.
|
||||
It cannot be copied, but can be <em>moved</em> to
|
||||
|
@ -2036,7 +2042,7 @@ all copies, and the object is deleted when the last
|
|||
where the resource releases take place.</li>
|
||||
|
||||
<li><code>std::unique_ptr</code> expresses ownership
|
||||
transfer using C++11's move semantics, which are
|
||||
transfer using move semantics, which are
|
||||
relatively new and may confuse some programmers.</li>
|
||||
|
||||
<li>Shared ownership can be a tempting alternative to
|
||||
|
@ -2320,9 +2326,8 @@ exceptions in Google open-source projects as well.
|
|||
Things would probably be different if we had to do it all
|
||||
over again from scratch.</p>
|
||||
|
||||
<p>This prohibition also applies to the exception handling related
|
||||
features added in C++11, such as
|
||||
<code>std::exception_ptr</code> and
|
||||
<p>This prohibition also applies to exception handling related
|
||||
features such as <code>std::exception_ptr</code> and
|
||||
<code>std::nested_exception</code>.</p>
|
||||
|
||||
<p>There is an <a href="#Windows_Code">exception</a> to
|
||||
|
@ -2546,7 +2551,14 @@ casts when explicit type conversion is necessary.
|
|||
will not compile if conversion can result in information loss. The
|
||||
syntax is also concise.</li>
|
||||
|
||||
|
||||
<li>Use <code>absl::implicit_cast</code>
|
||||
to safely cast up a type hierarchy,
|
||||
e.g., casting a <code>Foo*</code> to a
|
||||
<code>SuperclassOfFoo*</code> or casting a
|
||||
<code>Foo*</code> to a <code>const Foo*</code>. C++
|
||||
usually does this automatically but some situations
|
||||
need an explicit up-cast, such as use of the
|
||||
<code>?:</code> operator.</li>
|
||||
|
||||
<li>Use <code>static_cast</code> as the equivalent of a C-style cast
|
||||
that does value conversion, when you need to
|
||||
|
@ -2668,10 +2680,8 @@ localization, and security hardening.</p>
|
|||
<p>If you do use streams, avoid the stateful parts of the
|
||||
streams API (other than error state), such as <code>imbue()</code>,
|
||||
<code>xalloc()</code>, and <code>register_callback()</code>.
|
||||
Use explicit formatting functions (see e.g.,
|
||||
|
||||
<code>absl/strings</code>)
|
||||
rather than
|
||||
Use explicit formatting functions (such as
|
||||
<code>absl::StreamFormat()</code>) rather than
|
||||
stream manipulators or formatting flags to control formatting
|
||||
details such as number base, precision, or padding.</p>
|
||||
|
||||
|
@ -2848,7 +2858,7 @@ enable their use with <code>constexpr</code>. Do not use
|
|||
is
|
||||
<code>int</code>. If a program needs a variable of a
|
||||
different size, use a precise-width integer type from
|
||||
<code><stdint.h></code>, such as
|
||||
<code><cstdint></code>, such as
|
||||
<code>int16_t</code>. If your variable represents a
|
||||
value that could ever be greater than or equal to 2^31
|
||||
(2GiB), use a 64-bit type such as <code>int64_t</code>.
|
||||
|
@ -2858,7 +2868,7 @@ calculations which may require a larger type. When in doubt,
|
|||
choose a larger type.</p>
|
||||
|
||||
<p class="definition"></p>
|
||||
<p> C++ does not specify the sizes of integer types
|
||||
<p> C++ does not precisely specify the sizes of integer types
|
||||
like <code>int</code>. Typically people assume
|
||||
that <code>short</code> is 16 bits,
|
||||
<code>int</code> is 32 bits, <code>long</code> is 32 bits
|
||||
|
@ -3279,13 +3289,13 @@ auto i = y.Find(key);
|
|||
by eliminating type information that is obvious or irrelevant, so that
|
||||
the reader can focus on the meaningful parts of the code:</p>
|
||||
<pre class="neutralcode">std::unique_ptr<WidgetWithBellsAndWhistles> widget_ptr =
|
||||
absl::make_unique<WidgetWithBellsAndWhistles>(arg1, arg2);
|
||||
std::make_unique<WidgetWithBellsAndWhistles>(arg1, arg2);
|
||||
absl::flat_hash_map<std::string,
|
||||
std::unique_ptr<WidgetWithBellsAndWhistles>>::const_iterator
|
||||
it = my_map_.find(key);
|
||||
std::array<int, 6> numbers = {4, 8, 15, 16, 23, 42};</pre>
|
||||
|
||||
<pre class="goodcode">auto widget_ptr = absl::make_unique<WidgetWithBellsAndWhistles>(arg1, arg2);
|
||||
<pre class="goodcode">auto widget_ptr = std::make_unique<WidgetWithBellsAndWhistles>(arg1, arg2);
|
||||
auto it = my_map_.find(key);
|
||||
std::array numbers = {4, 8, 15, 16, 23, 42};</pre>
|
||||
|
||||
|
@ -3450,18 +3460,18 @@ ordering of fields than the <code>Point</code> example above.</p>
|
|||
<p class="cons"></p>
|
||||
<p>While designated initializers have long been part of the C standard and
|
||||
supported by C++ compilers as an extension, only recently have they made it
|
||||
into the draft C++ standard. They are on track for publishing in C++20.</p>
|
||||
into the C++ standard, being added as part of C++20.</p>
|
||||
|
||||
<p>The rules in the draft C++ standard are stricter than in C and compiler
|
||||
extensions, requiring that the designated initializers appear in the same order
|
||||
as the fields appear in the struct definition. So in the example above it is
|
||||
legal according to draft C++20 to initialize <code>x</code> and then
|
||||
<code>z</code>, but not <code>y</code> and then <code>x</code>.</p>
|
||||
<p>The rules in the C++ standard are stricter than in C and compiler extensions,
|
||||
requiring that the designated initializers appear in the same order as the
|
||||
fields appear in the struct definition. So in the example above, it is legal
|
||||
according to C++20 to initialize <code>x</code> and then <code>z</code>, but not
|
||||
<code>y</code> and then <code>x</code>.</p>
|
||||
|
||||
<p class="decision"></p>
|
||||
<p>Use designated initializers only in the form that is compatible with the
|
||||
draft C++20 standard: with initializers in the same order as the corresponding
|
||||
fields appear in the struct definition.</p>
|
||||
C++20 standard: with initializers in the same order as the corresponding fields
|
||||
appear in the struct definition.</p>
|
||||
|
||||
|
||||
|
||||
|
@ -3549,8 +3559,8 @@ std::sort(indices.begin(), indices.end(), [&](int a, int b) {
|
|||
<li>Default captures by value can be misleading because they do not prevent
|
||||
dangling-pointer bugs. Capturing a pointer by value doesn't cause a deep
|
||||
copy, so it often has the same lifetime issues as capture by reference.
|
||||
This is especially confusing when capturing 'this' by value, since the use
|
||||
of 'this' is often implicit.</li>
|
||||
This is especially confusing when capturing <code>this</code> by value,
|
||||
since the use of <code>this</code> is often implicit.</li>
|
||||
|
||||
<li>Captures actually declare new variables (whether or not the captures have
|
||||
initializers), but they look nothing like any other variable declaration
|
||||
|
@ -3600,14 +3610,18 @@ prefer to write:
|
|||
// reference.
|
||||
</pre>
|
||||
</li>
|
||||
<li>Use default capture by reference ([&]) only when the
|
||||
lifetime of the lambda is obviously shorter than any potential
|
||||
<li>Use default capture by reference (<code>[&]</code>) only when
|
||||
the lifetime of the lambda is obviously shorter than any potential
|
||||
captures.
|
||||
</li>
|
||||
<li>Use default capture by value ([=]) only as a means of binding a
|
||||
few variables for a short lambda, where the set of captured
|
||||
variables is obvious at a glance. Prefer not to write long or
|
||||
complex lambdas with default capture by value.
|
||||
<li>Use default capture by value (<code>[=]</code>) only as a means of
|
||||
binding a few variables for a short lambda, where the set of captured
|
||||
variables is obvious at a glance, and which does not result in
|
||||
capturing <code>this</code> implicitly. (That means that a lambda that
|
||||
appears in a non-static class member function and refers to non-static
|
||||
class members in its body must capture <code>this</code> explicitly or
|
||||
via <code>[&]</code>.) Prefer not to write long or complex lambdas
|
||||
with default capture by value.
|
||||
</li>
|
||||
<li>Use captures only to actually capture variables from the enclosing scope.
|
||||
Do not use captures with initializers to introduce new names, or
|
||||
|
@ -3789,76 +3803,6 @@ features to the list, so this list may be expanded in
|
|||
the future.</p>
|
||||
</div>
|
||||
|
||||
<h3 id="std_hash">std::hash</h3>
|
||||
|
||||
<p>Do not define specializations of <code>std::hash</code>.</p>
|
||||
|
||||
<p class="definition"></p>
|
||||
<p><code>std::hash<T></code> is the function object that the
|
||||
C++11 hash containers use to hash keys of type <code>T</code>,
|
||||
unless the user explicitly specifies a different hash function. For
|
||||
example, <code>std::unordered_map<int, std::string></code> is a hash
|
||||
map that uses <code>std::hash<int></code> to hash its keys,
|
||||
whereas <code>std::unordered_map<int, std::string, MyIntHash></code>
|
||||
uses <code>MyIntHash</code>.</p>
|
||||
|
||||
<p><code>std::hash</code> is defined for all integral, floating-point,
|
||||
pointer, and <code>enum</code> types, as well as some standard library
|
||||
types such as <code>string</code> and <code>unique_ptr</code>. Users
|
||||
can enable it to work for their own types by defining specializations
|
||||
of it for those types.</p>
|
||||
|
||||
<p class="pros"></p>
|
||||
<p><code>std::hash</code> is easy to use, and simplifies the code
|
||||
since you don't have to name it explicitly. Specializing
|
||||
<code>std::hash</code> is the standard way of specifying how to
|
||||
hash a type, so it's what outside resources will teach, and what
|
||||
new engineers will expect.</p>
|
||||
|
||||
<p class="cons"></p>
|
||||
<p><code>std::hash</code> is hard to specialize. It requires a lot
|
||||
of boilerplate code, and more importantly, it combines responsibility
|
||||
for identifying the hash inputs with responsibility for executing the
|
||||
hashing algorithm itself. The type author has to be responsible for
|
||||
the former, but the latter requires expertise that a type author
|
||||
usually doesn't have, and shouldn't need. The stakes here are high
|
||||
because low-quality hash functions can be security vulnerabilities,
|
||||
due to the emergence of
|
||||
<a href="https://emboss.github.io/blog/2012/12/14/breaking-murmur-hash-flooding-dos-reloaded/">
|
||||
hash flooding attacks</a>.</p>
|
||||
|
||||
<p>Even for experts, <code>std::hash</code> specializations are
|
||||
inordinately difficult to implement correctly for compound types,
|
||||
because the implementation cannot recursively call <code>std::hash</code>
|
||||
on data members. High-quality hash algorithms maintain large
|
||||
amounts of internal state, and reducing that state to the
|
||||
<code>size_t</code> bytes that <code>std::hash</code>
|
||||
returns is usually the slowest part of the computation, so it
|
||||
should not be done more than once.</p>
|
||||
|
||||
<p>Due to exactly that issue, <code>std::hash</code> does not work
|
||||
with <code>std::pair</code> or <code>std::tuple</code>, and the
|
||||
language does not allow us to extend it to support them.</p>
|
||||
|
||||
<p class="decision"></p>
|
||||
<p>You can use <code>std::hash</code> with the types that it supports
|
||||
"out of the box", but do not specialize it to support additional types.
|
||||
If you need a hash table with a key type that <code>std::hash</code>
|
||||
does not support, consider using legacy hash containers (e.g.,
|
||||
<code>hash_map</code>) for now; they use a different default hasher,
|
||||
which is unaffected by this prohibition.</p>
|
||||
|
||||
<p>If you want to use the standard hash containers anyway, you will
|
||||
need to specify a custom hasher for the key type, e.g.,</p>
|
||||
<pre>std::unordered_map<MyKeyType, Value, MyKeyTypeHasher> my_map;
|
||||
</pre><p>
|
||||
Consult with the type's owners to see if there is an existing hasher
|
||||
that you can use; otherwise work with them to provide one,
|
||||
or roll your own.</p>
|
||||
|
||||
<p>We are planning to provide a hash function that can work with any type,
|
||||
using a new customization mechanism that doesn't have the drawbacks of
|
||||
<code>std::hash</code>.</p>
|
||||
|
||||
|
||||
|
||||
|
@ -4491,6 +4435,7 @@ operation.</p>
|
|||
preceding it that describe what the function does and how to use
|
||||
it. These comments may be omitted only if the function is simple and
|
||||
obvious (e.g., simple accessors for obvious properties of the class).
|
||||
Private methods and functions declared in `.cc` files are not exempt.
|
||||
Function comments should be written with an implied subject of
|
||||
<i>This function</i> and should start with the verb phrase; for example,
|
||||
"Opens the file", rather than "Open the file". In general, these comments do not
|
||||
|
@ -4603,7 +4548,7 @@ obvious. For example:</p>
|
|||
<h4>Global Variables</h4>
|
||||
|
||||
<p>All global variables should have a comment describing what they
|
||||
are, what they are used for, and (if unclear) why it needs to be
|
||||
are, what they are used for, and (if unclear) why they need to be
|
||||
global. For example:</p>
|
||||
|
||||
<pre>// The total number of test cases that we run through in this regression test.
|
||||
|
@ -4618,33 +4563,7 @@ non-obvious, interesting, or important parts of your code.</p>
|
|||
<h4>Explanatory Comments</h4>
|
||||
|
||||
<p>Tricky or complicated code blocks should have comments
|
||||
before them. Example:</p>
|
||||
|
||||
<pre>// Divide result by two, taking into account that x
|
||||
// contains the carry from the add.
|
||||
for (int i = 0; i < result->size(); ++i) {
|
||||
x = (x << 8) + (*result)[i];
|
||||
(*result)[i] = x >> 1;
|
||||
x &= 1;
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h4>Line-end Comments</h4>
|
||||
|
||||
<p>Also, lines that are non-obvious should get a comment
|
||||
at the end of the line. These end-of-line comments should
|
||||
be separated from the code by 2 spaces. Example:</p>
|
||||
|
||||
<pre>// If we have enough memory, mmap the data portion too.
|
||||
mmap_budget = max<int64_t>(0, mmap_budget - index_->length());
|
||||
if (mmap_budget >= data_size_ && !MmapData(mmap_chunk_bytes, mlock))
|
||||
return; // Error already logged.
|
||||
</pre>
|
||||
|
||||
<p>Note that there are both comments that describe what
|
||||
the code is doing, and comments that mention that an
|
||||
error has already been logged when the function
|
||||
returns.</p>
|
||||
before them.</p>
|
||||
|
||||
<h4 class="stylepoint_subsection" id="Function_Argument_Comments">Function Argument Comments</h4>
|
||||
|
||||
|
@ -4662,7 +4581,8 @@ one of the following remedies:</p>
|
|||
values self-describing.</li>
|
||||
|
||||
<li>For functions that have several configuration options, consider
|
||||
defining a single class or struct to hold all the options,
|
||||
defining a single class or struct to hold all the options
|
||||
,
|
||||
and pass an instance of that.
|
||||
This approach has several advantages. Options are referenced by name
|
||||
at the call site, which clarifies their meaning. It also reduces
|
||||
|
@ -4882,7 +4802,7 @@ encoded as UTF-8, because that will produce incorrect
|
|||
output if the compiler does not interpret the source file
|
||||
as UTF-8. </p>
|
||||
|
||||
<p>You shouldn't use the C++11 <code>char16_t</code> and
|
||||
<p>You shouldn't use <code>char16_t</code> and
|
||||
<code>char32_t</code> character types, since they're for
|
||||
non-UTF-8 text. For similar reasons you also shouldn't
|
||||
use <code>wchar_t</code> (unless you're writing code that
|
||||
|
@ -5630,7 +5550,9 @@ trailing whitespace at the end of a line.</p>
|
|||
|
||||
<h4>General</h4>
|
||||
|
||||
<pre>void f(bool b) { // Open braces should always have a space before them.
|
||||
<pre>int i = 0; // Two spaces before end-of-line comments.
|
||||
|
||||
void f(bool b) { // Open braces should always have a space before them.
|
||||
...
|
||||
int i = 0; // Semicolons usually have no space before them.
|
||||
// Spaces inside braces for braced-init-list are optional. If you use them,
|
||||
|
@ -5865,32 +5787,6 @@ occasionally need to break on Windows:</p>
|
|||
<code>resource.h</code> and contain only macros, do not
|
||||
need to conform to these style guidelines.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="Parting_Words">Parting Words</h2>
|
||||
|
||||
<p>Use common sense and <em>BE CONSISTENT</em>.</p>
|
||||
|
||||
<p>If you are editing code, take a few minutes to look at the
|
||||
code around you and determine its style. If they use spaces
|
||||
around their <code>if</code> clauses, you should, too. If their
|
||||
comments have little boxes of stars around them, make your
|
||||
comments have little boxes of stars around them too.</p>
|
||||
|
||||
<p>The point of having style guidelines is to have a common
|
||||
vocabulary of coding so people can concentrate on what you are
|
||||
saying, rather than on how you are saying it. We present global
|
||||
style rules here so people know the vocabulary. But local style
|
||||
is also important. If code you add to a file looks drastically
|
||||
different from the existing code around it, the discontinuity
|
||||
throws readers out of their rhythm when they go to read it. Try
|
||||
to avoid this.</p>
|
||||
|
||||
|
||||
|
||||
<p>OK, enough writing about writing code; the code itself is much
|
||||
more interesting. Have fun!</p>
|
||||
|
||||
<hr>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user