编码风格

Naming

  • Use descriptive names for global variables and functions.
  • Naming should follow the snake_case convention.
  • Public function names should include capitalized module identifier, object and property they're operating and operation itself. Very familiar with RNA callbacks names: BKE_object_foo_get(...) / BKE_object_foo_set(...):
/* Don't: */
ListBase *curve_editnurbs(Curve *cu);
/* Do: */
ListBase *BKE_curve_editnurbs_get(Curve *cu);
  • Private functions should not start with capitalized module identifier. They can, however, start with lower case module identifier:
/* Don't: */
static void DRW_my_utility_function(void);
/* Do: */
static void drw_my_utility_function(void);
static void my_other_utility_function(void);
  • Local variables should be short and to the point.

Macros, Enums, Inline functions

  • Names of macros defining constants and labels in enums should be capitalized.
  • Macro names should be capitalized.
  • Enums used in DNA files should have explicit values assigned.

Function arguments

Return arguments

In C its common to use arguments to return values (since C only supports returning a single value).

  • return arguments should have a r_ prefix, to denote they are return values.
  • return arguments should be grouped at the end of the argument list.
  • optionally, put these arguments on a new line (especially when the argument list is already long and may be split across multiple lines anyway).
/* Don't: */
void BKE_curve_function(Curve *cu, int *totvert_orig, int totvert_new, float center[3]);

/* Do: */
void BKE_curve_function(Curve *cu, int totvert_new, int *r_totvert_orig, float r_center[3]);

Braces

Always Use Braces

Braces are to be used even when not strictly necessary.

/* Don't: */
  if (a == b)
    d = 1;
  else
    c = 2;

/* Do: */
  if (a == b) {
    d = 1;
  }
  else {
    c = 2;
  }
/* Don't: */
  for (int i = 0; i < 3; i++)
    dest[i] = src[i];

/* Do: */
  for (int i = 0; i < 3; i++) {
    dest[i] = src[i];
  }

C/C++ Comments

C-style comments should be used in C++ code.

Adding dead code is discouraged. In some cases, however, having unused code is useful (gives more semantic meaning, provides reference implementation, ...).

It is fine having unused code in this cases. Use // for a single-line code, and #if 0 for multi-line code. And always explain what the unused code is about.

  • When using multiline comments, markers (star character, '*') should be used in the beginning of every line of comment:
/* Special case: ima always local immediately. Clone image should only
 * have one user anyway. */

NOT

/* Special case: ima always local immediately. Clone image should only
   have one user anyway. */

Comment Sections

It's common to use comments to group related code in a file. Blender's convention is to use doxygen formatted sections.

/* -------------------------------------------------------------------- */
/** \name Title of Code Section
 * \{ */

... code ...

/** \} */

You may include descriptive text about the section under the title:

/* -------------------------------------------------------------------- */
/** \name Title of Code Section
 *
 * Explain in more detail the purpose of the section.
 * \{ */

... code ...

/** \} */

For headers that mainly contain declarations, the following non-doxy sections are also acceptable:

/* --------------------------------------------------------------------
 * Name of the section.
 */

Or with some extra text:

/* --------------------------------------------------------------------
 * Name of the section.
 *
 * Optional description.
 */

API Docs

When writing more comprehensive comments that include for example, function arguments and return values, cross references to other functions... etc, we use DoxyGen syntax comments.

If you choose to write doxygen comments, here's an example of a typical doxy comment (many more in blenders code).

/**
 * Return the unicode length of a string.
 *
 * \param start: the string to measure the length.
 * \param maxlen: the string length (in bytes)
 * \return the unicode length (not in bytes!)
 */
size_t BLI_strnlen_utf8(const char *start, const size_t maxlen);

Note that this is just the typical paragraph style used in blender with an extra leading '*'.

Unity builder namespace

Files which a part of a unity build should have their private-to-compile-unit symbols inside a blender::<module>::unity_build_<file>_cc:

namespace blender::deg {

namespace unity_build_deg_node_cc {

/* Function which is only used within the node.cc file */
static void some_private_function() { ... }

}  // namespace unity_build_deg_node_cc

/* Function which is declared in a public header (is a part of public API). */
void function_which_is_public_in_the_module() { ... }

}  // namespace blender::deg

This ensures that concatenation of files for unity builder does not cause symbol conflicts, while keeping it clear for the developers the intent of the namespace which is unique to the translation unit.

Variable Scope

Try to keep the scope of variables as small as possible.

/* Don't: */
int a, b;

a = ...;
...
b = ...;


/* Do: */
int a = ...;
...
int b = ...;

Const

Use const whenever possible. Try to write your code so that const can be used, i.e. prefer declaring new variables instead of mutating existing ones.

Certain const declarations in function parameters are irrelevant to the declaration and only necessary in the function definition:

/* No const necessary in declaration because `param` is passed by value. */
void func(float param);

/* In the definition, it means that `param` will not change value. */
void func(const float param) { ... }

Class Layout

Classes should be structured as follows. Parts that are not needed by a specific class should just be skipped.

class X {
  /* using declarations */
  /* static data members */
  /* non-static data members */

 public:
  /* default constructor */
  /* other constructors */
  /* copy constructor */
  /* move constructor */

  /* destructor */

  /* copy assignment operator */
  /* move assignment operator */
  /* other operator overloads */

  /* all public static methods */
  /* all public non-static methods */

 protected:
  /* all protected static methods */
  /* all protected non-static methods */

 private:
  /* all private static methods */
  /* all private non-static methods */
};
 
posted @ 2023-06-24 03:09  冂冋冏囧  阅读(7)  评论(0编辑  收藏  举报