GSMP - General Sound Manipulation Program (c) 2000-2002 René Rebe and Valentin Ziegler Information for syntax and coding conventions in GSMP or one of its basic libraries (i.e. DAM). General guide: -------------- - The main programming language used in GSMP is C++. And with C++ we actually mean C++. Not C with classes and not some other crippled variant. C++ with all it's STL, RTTI and templates. - Modern object-oriented and generic methods should be used: - using object hierachies and polymorphism - creating templates where possible - using traits for compile-time features and class aspects instead of preprocessor directives - using the STL where resonable A good starting point to learn more about this: - The C++ Programming Language - Bjarne Stroustrup (#1) - The C++ Standard Library - Nicolai M. Josuttis (#2) - Design Patterns - Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides (#3) Files --------------------------- - header files have the extention ".hh". - source-files ".cc". - template and inline code is placed into an extra file ".tcc". - in each project, there should be a directory named "include" for common used headers. There should be a subdirectory "include/template" for the ".tcc" files and "src" for the source- files ".cc". - each source directory has its own Makefile. Theese are "executed" by the Makefiles in the toplevel directory. Header files --------------------------- - the header files are protected against multiple inclusion by following preprocessor directive: #ifndef PROJECT__FILENAME_HH__ #define PROJECT__FILENAME_HH__ /* some content */ #endif // PROJECT__FILENAME_HH__ where FILENAME is the name of the header in capital letters and PROJECT could be DAM or GSMP or sth. - also protect tcc files agains accidental inclusion: in filename.tcc: #ifndef PROJECT__FILENAME_TMPL__ #error "This file is included by .... " #error "Include that file instead." #endif inclusion of .tcc file at end of filename.hh: #define PROJECT__FILENAME_TMPL__ #include "template/filename.tcc" #undef PROJECT__FILENAME_TMPL__ - also follow the directions in the "namespace" section. Naming conventions: ---------------------------- "... Choosing good names is an art." - Bjarne Stroustrup (#1) We changed theese conventions many times, so the old code from 0.0.5 does not match them. - Class and method names have capital letters at the beginning and on word boundaries. e.g.: MixerNode, GsmpCanvas, PcmBuffer ... - Instance names start with an non-capital letter and _ on word boundaries. e.g.: current_layer - unspecialized base-classes of templates should begin with "Basic" like template Definitionmap : public BasicDefinitionMap {}; - A constructor parameter which takes a value copied into a class member should be named like the member itself but start with an i_ (abbr. for init) - aggregated objects should start with no prefix - or only rare cases with an m_ (abbr. for my or member) - temporary calculated values in methods should start with t_ (abbr. for temp/ temporary) - return values may be prefixed with r_ (abbr. for return) - template typenames are written in capitals: template Indenting: ------------------------------ - indenting space it the XEmacs default of two characters - between names and operators should be one space. e.g.: - t_layer -> Length (); ^ ^ ^ - pointer and references should be specified without space after the type. e.g.: - MixerNode* t_mixer; ^ - VoodooClass::SetStart (const sample_index& start); ^ This reflects that it is a pointer or reference TYPE! - Namespace or scope operator should not be sperated by spaces. e.g.: - Gsml::TrackLayer::iterator i .... ^^ ^^ - curly brackets enclosing blocks are placed like in their own lines: if (false) { cout << "detected compiler : visual c++" << endl; } and not like this: if (false) { cout << endl; } This convention also holds for class- and functionbodies. However, there are some exceptions to this rule, like empty classes class DAM::Empty {}; or short inline functions ( longer ones should be placed into an .tcc file !) class Foo { bool Enabled {return enabled;} } Namespaces: ------------------------ - all definitions have to be placed in some namespace: - related classes should be grouped in the same namespaces namespace Greek { class Zeus {}; class Hermes {}; ... } - "using namespace" directives must not be used in .hh header files. "In complex code 'using namespace X;' might lead to accidental name clashes or, worse, to different behaviour due to some obscure over- loading rules. You should never use a using directive when the context is not clear (such as in header files, modules or libriaries)." - Nicolai M. Josuttis (#2) Preprocessor Tricks: ------------------------- - #defines should be avoided. Constants should be used for type safety. - #ifdef-style code should be avoided. Even for debug stuff. There is nothing that can not be done in C++ code! Debug statments can be eliminated by the compiler, if the expression is determinalble during compile time. Consider using trait-classes with "static const" members instead. This way it is made sure the debug code is syntactically correct even when compiling with debugging disabled. Other conventions: ------------------------- - The code should be const correct - that is non modified reference arguments should be const and functions not modifying the class state should be declated const, too. - References (as alternative to pointers) for modified arguments must not not be used since: "Functions that modify call-by-reference arguments can make the programs hard to read and should most often be avoided." - Bjarne Stroustrup (#1) Glossary: ------------------------- Here we included a list of commonly used abbreviations and naming conventions: channel: cur_: Iterators or ordinary pointers pointing to a "current" object in a container, or container like structure, should be prefixed "cur_". dst: If an object is the "destination" of an operation it should include the abbreviation dst in the object name. Get-/SetVarName: Should be avoidded (where possible) and just a set of VarName methods should return or set the property. index: The use of the name index in varable names, unlike dst and src, should not be abbreviated. src: If an object is the "source" for an operation it should include the abbreviation src in the object name.