C++ Coding 指南

来源:互联网 发布:手机淘宝卖家怎么注册 编辑:程序博客网 时间:2024/05/17 09:27

This document is a companion to theC++ Coding Standard. It collects various informalhints on aspects to consider when designing and implementing code in the FOO software stack.

  • C++ Coding Guidelines
    • Available C++11 features
    • C++11 hints
      • Watch out for user-defined literals
      • No need to add space between “>” characters in template argument lists
      • auto specifier
      • Scoped (strongly-typed) enum
      • Container literals (list initialization)
      • static_assert
      • std::shared_ptr andstd::weak_ptr
      • std::unique_ptr
      • std::bind,std::function and std::ref
    • Logging
      • Log levels
      • How to log
      • Debug log messages
      • How to write good log messages

Available C++11 features

In code compiled for all STB toolchains (i.e., most code), we have support forthe subset of C++11 features implemented by the oldest GCC version in ourtoolchains. The lower bar is currentlyGCC 4.4:

              

In code only compiled with newer toolchains, it is allowed to use newerfeatures, but please refrain from using newer features in code that in thefuture might be useful for toolchains with older GCC versions. One notable caseis unit tests where there are no restrictions since such code is built only bythe host compiler.

See also C++0x/C++11 Support in GCC.

C++11 hints

Here is a summary of things to consider when writing new code.

Watch out for user-defined literals

Before C++11:

printf("x is %"PRIu64", y is %"PRIu64"\n", x, y);

Now:

printf("x is %" PRIu64 ", y is %" PRIu64 "\n", x, y);

Spaces must be added around macros as shown above since the code otherwise willfail to compile. This is because the code is interpreted as referring to auser-defined literal.

No need to add space between “>” characters in template argument lists

Before C++11:

std::map<int, std::vector<int> >

Now:

std::map<int, std::vector<int>>

auto specifier

Before C++11:

TContainer::const_iterator iter = Container.find(x);

Now:

auto iter = Container.find(x);

See also auto specifier.

Scoped (strongly-typed) enum

Before C++11:

enum TStatus {  STATUS_READY,  STATUS_SET,  STATUS_GO};

Now:

enum class TStatus {  READY,  SET,  GO};

See also scopedenumerations.

Container literals (list initialization)

Before C++11:

std::vector<int> x;x.push_back(1);x.push_back(2);x.push_back(3);

Now:

std::vector<int> x = {1, 2, 3};// Or:std::vector<int> x({1, 2, 3});// Or:std::vector<int> x{1, 2, 3};

Before C++11:

std::map<std::string, int> x;x["a"] = 1;x.insert(std::make_pair("b", 2));x.insert(std::map<std::string, int>::value_type("c", 3));

Now:

std::map<std::string, int> x = {{"a", 1}, {"b", 2}, {"c", 3}};// Or:std::map<std::string, int> x({{"a", 1}, {"b", 2}, {"c", 3}});// Or:std::map<std::string, int> x{{"a", 1}, {"b", 2}, {"c", 3}};

See also listinitialization.

static_assert

Before C++11:

#include <boost/static_assert.hpp>BOOST_STATIC_ASSERT(x);

Now:

static_assert(x, "message");

std::shared_ptr andstd::weak_ptr

Before C++11:

#include <boost/shared_ptr.hpp>#include <boost/weak_ptr.hpp>boost::shared_ptr<TExample> s;boost::weak_ptr<TExample> w;

Now:

#include <memory>std::shared_ptr<TExample> s;std::weak_ptr<TExample> w;

See alsostd::shared_ptr andstd::weak_ptr.

std::unique_ptr

Before C++11:

#include <boost/scoped_ptr.hpp>boost::scoped_ptr<TExample> x;

Now:

#include <memory>const std::unique_ptr<TExample> x; // If no call to the reset method is needed.std::unique_ptr<TExample> x;       // If a call to the reset method is needed.

Before C++11:

#include <memory>std::auto_ptr<TExample> x;

Now:

#include <memory>std::unique_ptr<TExample> x;

Note: Use std::move tomove value out of an std::unique_ptr.

See alsostd::unique_ptr.

std::bind,std::function andstd::ref

Before C++11:

#include <boost/bind.hpp>#include <boost/function.hpp>#include <boost/ref.hpp>typedef boost::function<void ()> TFunction;boost::bind(&TClass::Method, boost::ref(x), _1);

Now:

#include <functional>using std::placeholders::_1;typedef std::function<void ()> TFunction;std::bind(&TClass::Method, std::ref(x), _1);

See alsostd::bind,std::functionandstd::ref.

Logging

Log levels

LevelExplanationExampleFatalA fatal error has occurred that can not be handled and prevents further execution. This log line should always be followed by a program termination – never use one without the other (tip: useKABORT). Fatals should never be reached in production code and always indicate a bug somewhere in the system.“Could not connect to name service”, “Caught an unknown exception”ErrorAn error has occurred that affects some core functionality but can be handled and does not prevent further execution. Errors may be the symptoms of bugs, but may also be the result of problems in the environment/configuration/input.“VoD server not found”, “Child process exited unexpectedly”WarningSomething out of the ordinary has happened but does not have any direct impact on the current task. It may be caused by input that is missing or out of bounds. It can be the symptom of bugs in the calling code.“Missing configuration, using default”, “Resource already open”NoteThe code has reached a point where it is informative to put a message in the log. It could be triggered by a state change, an event or user input that provides useful information to a working system.“HDMI connected”, “Entering standby”DebugUsed to provide information that can be used in debugging without requiring specific knowledge about the code internals. It could be minor state changes or extra information in addition to another log message. No pure development debugging messages should be enabled in production code.“IP address renewed”, “Initialization done, entering event loop”

How to log

All FOO code must, when possible, use theKDebug macros for logging:

KNOTE("log message");

Do not use TTracker or fprintf(stderr, ...) explicitly (unless necessary):

TTracker::GetProcessTracker()->Note("log message");Tracker->Note("log message");fprintf(stderr, "<N>log message\n");

Note: Producing output from commandline programs, e.g. toish, is not“logging”.

Debug log messages

Log messages on the debug level (“debug log messages”) can be used duringdevelopment but should normally not exist in production code. This is to avoidspamming the log, since too much logging causes performance problems and canconceal other log messages that indicate a real problem. In short: only logreal problems or points of general interest in production code.

During development, it may be useful to have debug log messages to tracefunction entry/exit (tip: useKTRACE_FUNCTION,variable values or other points of interest. Before the code is submitted tothe revision control system, debug log messages should be removed or protectedby a define (that is undefined by default). Alternatively, let the debug logmessages beenabled at runtime.Note that runtime-enabled debug log messages still have a performance penalty,so use them sparingly.

How to write good log messages

Some general tips on how to write good log messages:

  • Be concise. Logs should be informative and easy to understand. Prefer short expressive statements to longer, grammatically flawless sentences. Avoid capital letters and special characters just to get attention.
  • Avoid spamming. Do not repeat yourself unless there is something new to report. It is often worth a few extra lines of code to avoid log spamming. Think one extra time before adding log lines to heavily shared code.
  • Use the correct levels. Understand what level is appropriate for each log line. Remember that the failure of some functionality may be the result of an explicit configuration and thus could be expected. Keep in mind that traces often are filtered out and no warnings/errors/fatals should be shown when the box operates as expected.
0 0
原创粉丝点击