/** * \file * <!-- * Copyright 2004,2005,2006,2008 Develer S.r.l. (http://www.develer.com/) * All rights reserved. * --> * * \version $Id: coding_style.cpp 22211 2008-08-04 09:59:02Z bernie $ * \author Bernie Innocenti <bernie@codewiz.org> * \author Simone Zinanni <s.zinanni@develer.com> * \author Stefano Fedrigo <aleph@develer.com> * * * \brief Develer indentation and naming style for C/C++-like languages. * * General rules: * * - Begin all new files with standard headers like this one; * * - For substantial edits to existing files, remember to update the * copyright years and add yourself to list of authors; * * - Use meaningful and descriptive commit log messages; * * - Use correct capitalization and punctuation even in comments * and in commit log messages. * * * Naming conventions quick reference: * * - ClassName::memberFunction(const TypeName &arg_name); * * - ClassName::member_variable * ClassName::_private_member_variable_with_accessor * * - static const int CONSTANT_VALUE = 42; * enum { ALSO_A_CONSTANT = CONSTANT_VALUUE * 666 }; * \#define YET_ANOTHER_CONSTANT (CONSTANT_VALUE * ALSO_A_CONSTANT) * * - template <class Cont, class Iter, typename T> * void foo(); */ /* * Place local header inclusions before system headers because it helps * catching local headers which don't stand on their own. * * Preferably add a comment to each system header to make it clear why * you're including it. It helps tracking which headers can be dropped * while performing maintainance work. */ #include "local.h" #include "develer/stuff.h" #include <iostream> // std::cout #include <unistd.h> // open(), write() #include <vector.h> // BAD: Don't use pre-ISO C++ 98 headers /* * GOOD: import only what you really use often. Use the std prefix * for things you use sparingly. */ using std::string; using std::cout; /* * BAD: don't import _everything_ from the std namespace unless you * really need *lots* of stuff from it. * * Polluting the namespace with "using" in public interface headers is BAD. * Use explicit namespace qualification instead. */ using namespace std; // Indent preprocessor commands like this: #ifdef __WIN32__ #define SEPARATOR '\\' #define BLA 42 #define BOO(x) ((x) * 3) void myfunc(SOCKET socket); #else // !__WIN32__ #define SEPARATOR '/' #define BLA /*nop*/ #define BOO(x) (0) void nuke_host(int socket); #endif // !__WIN32__ /// Global variables are lower case, and have a unique, distinctive name: int serial_fd; std::list<Window *> window_list; /** * Use English words for variable and class names if possible. * Common abbreviations and acronyms are allowed. * * English is also the preferred language for output messages, * comments and documentation. Some projects may override this * rule to satisfy client request. */ static struct UserAccount default_system_user; // fwd decl class MainWindow; /** * Document all public classes briefly (use Doxygen's auto-brief feature). * * Write a detailed description of the class * general design, its role, and the intended use. * * \note Use Doxygen markup sparingly and consistently. * Use JavaDoc style markup only in Java code. */ class FooBar : public Base { /* * Place public definitions first in class bodies. */ // public definitions public: /// Constants and enum labels are all in UPPERCASE. static const int FOO_BAR_LENGTH = 100; /// Color, not Colors (avoid plurals). enum Color { NONE = -1, ///< Document only non-obvious values. TRANSPARENT = -2, ///< Don't use TABs to align comments. RED = 0, GREEN, BLUE, CYAN, MAGENTA, YELLOW, COLOR_CNT ///< Total number of available colors. }; /** * Document interface structures. */ struct Point { int x, y; ///< Document x and y int color; ///< Document the color }; /// Also document other public definitions. typedef std::vector<int> container_type; /* * Public, protected and private data members should be * placed right after definitions and before member functions. */ // public data members public: /// Size of FooBar (in millibars). size_t size; /// Don't capitalize member variables. Use underscores to break words. std::string multi_word_name; /// BAD: don't ever use hungarian notation and capitalization! LPCSTR lpszSomeVariableName; // protected data members protected: /** * Non-public attributes with "get" or "set" accessors are named after * their accessors, prefixed with an underscore to avoid using them * directly. */ int _color; /// Non-public attributes without accessors don't need a prefix. int fuzzyness; /* * Public member functions come before protected and private members. * Constructors are placed before any other member functions. */ // construction public: // default ctor FooBar() { /* nop */ } /** * Some constructors need to be documented, others might be too simple * to be worth it. */ FooBar(int color, int shape) : Base(shape) { this.color = color; }; // vdtor virtual ~FooBar(); // public methods public: /** * Document interface methods. * * \param file_name Also document their parameters. * \param write Unless their meaning is obvious. */ void methodName(const char *file_name, bool write = false); /// You can also use one-liners for simple interfaces. inline bool anInlineMethod(void *buf) { // Declare main variables at the top of the function body. bool result = false; int iterations_cnt = 100; // BAD: don't use old-style casts char *avoid_this = (char *)buf; // GOOD: use new-style casts only char *str = static_cast<char *>(buf); /* * For consistency with STL iterators, prefer pre-increment * over post-increment when it does not make any difference. */ for (int i = 0; i < strlen(str); ++i) { /* * Place a space between if, for, while and the * opening parentheses. */ if (str[i] == 'a') std::cout << str[i] << std::endl; } Window *w = getWindow(); FileWindow *file_window; if ((fw = dynamic_cast<FileWindow *>(file_window))) { fw->open(); /* Break long lines like this. * * We don't enforce a strict limit for the right margin; * use common sense to improve readability. */ if ((fw->selectedFile() && !(fw->userAbort())) || (fw->multipleSelection && fw->filesSelected() > 2)) { if (!resume_from_errors) panic(); } else { // success result = true; } fw->close(); } return result; } void indentationExample() { /* * GOOD: Always use TABs to indent your code. * * You can use whatever TAB size you prefer (usually 4 or 8). */ /* * BAD: Don't mix TABs and spaces! * If you do, your code will look like shit on anything but your editor. * Here, we've set the editor with a TAB size of 6. */ // BAD: Don't leave hidden extra blanks before EOLs /* * GOOD: Use spaces instead of TABs for drawings and tables * * VCC Vref * | | * +-+ | * | | Rk | * | | | * +-+ | +-----+ * | +-| ADC | * V1 +---------| | * | +-----+ * /// GND */ /* * GOOD: Use TABs _only_ for indentation, and spaces only * for formatting columns and tables of aligned values. */ const float NTC_MIN_TEMP = 5.5; ///< Minimum temperature (Celsius degrees) const float NTC_MAX_TEMP = 49.0; ///< Maximum temperature (Celsius degrees) const int NTC_STEP = 2; ///< Increase between steps (ADC units) const int NTC_STEPS_COUNT = (NTC_MAX_TEMP - NTC_MIN_TEMP) / NTC_STEP; } // public accessors public: /// Accessor to get an attribute (NOTE: No "get" prefix). int color() const { return _color; } /// Accessor to set an attribute (NOTE: Use "set" prefix). int setColor(int c) { _color = c; } // disable unused default/copy constructors and assignment operator private: //FooBar(); FooBar(const FooBar &); FooBar &operator=(const FooBar &); }; /// Out-of-line declaration. void FooBar::methodName(const char *file_name, bool write /* = false */) { try { Socket s(file_name, write); s.write("Hello, world!\n"); } catch (io_exception &e) { std::cout << "Error!\n"; throw e; } } /** * \name Foo handling. * * When you are using a procedural language such as C and you need to group a * set of functions operating on the same entity, these functions must be * prefixed with the (short) name of the module they refer to: * * \{ */ extern void foo_open(void); extern void foo_close(void); extern void foo_isOpen(void); extern void foo_getSize(void); //\} /** * Template arguments are capitalized, just like class names. * * These are the preferred names for a few typical template * arguments: * - Cont: any STL-like container; * - Iter: any STL-like iterator; * - FwdIter: any STL-like forward iterator; * - ResultType: any type used to return a value; * - T, T1, T2: any type, generally used for values to be stored or passed. * * Also note that we use "class" to mean "pass me something that looks like * a class" and "typename" to mean "any type is welcome". */ template <class Cont, class FwdIter, typename SepType> void split(Cont &out, FwdIter begin, FwdIter end, SepType sep); /* Don't forget extra blank lines before EOF */
