Noeud « Previous »: File Conventions, Noeud « Up »: Coding Style



2.3.6 Matters of Style

The following items are more a matter of style than the others. Nevertheless, you are asked to follow this style.

— Rule: Order class members by visibility first

When declaring a class, start with public members, then protected, and last private members. Inside these groups, you are invited to group by category, i.e., methods, types, and members that are related should be grouped together. The motivation is that private members should not even be visible in the class declaration (but of course, it is mandatory that they be there for the compiler), and therefore they should be “hidden” from the reader.

This is an example of what should not be done:

          class Foo
          {
          public:
            Foo (std::string, int);
            virtual ~Foo ();

          private:
            typedef std::string string_type;
          public:
            std::string bar_get () const;
            void bar_set (std::string);
          private:
            string_type bar_;

          public:
            int baz_get () const;
            void baz_set (int);
          private:
            int baz_;
          }
     

rather, write:

          class Foo
          {
          public:
            Foo (std::string, int);
            virtual ~Foo ();

            std::string bar_get () const;
            void bar_set (std::string);

            int baz_get () const;
            void baz_set (int);

          private:
            typedef std::string string_type;
            string_type bar_;
            int baz_;
          }
     

and add useful Doxygen comments.

— Rule: Prefer Doxygen Documentation to plain comments

We use Doxygen (voir Doxygen) to maintain the developer documentation of the Tiger Compiler.

— Rule: Use the Imperative

Use the imperative when documenting, as if you were giving order to the function or entity you are describing. When describing a function, there is no need to repeat “function” in the documentation; the same applies obviously to any syntactic category. For instance, instead of:

          /// \brief Swap the reference with another.
          /// The method swaps the two references and returns the first.
          ref& swap (ref& other);
     

write:

          /// \brief Swap the reference with another.
          /// Swap the two references and return the first.
          ref& swap (ref& other);
     

The same rules apply to writing ChangeLogs.

— Rule: Write Documentation in Doxygen

Documentation is a genuine part of programming, just as testing. The quality of this documentation can change the grade.

— Rule: Use \directive

Prefer backslash (\) to the commercial at (@) to specify directives.

— Rule: Prefer C Comments for Long Comments

Prefer C comments (/** ... */) to C++ comments (/// ...). This is to ensure consistency with the style we use.

— Rule: Prefer C++ Comments for One Line Comments

Because it is lighter, instead of

          /** \brief Name of this program. */
          extern const char *program_name;
     

prefer

          /// Name of this program.
          extern const char *program_name;
     

For instance, instead of

     /* Construct an InterferenceGraph. */
     InterferenceGraph (const std::string &name,
                        const assem::instrs_t& instrs, bool trace = false);

or

     /** @brief Construct an InterferenceGraph.
      ** @param name    its name, hopefully based on the function name
      ** @param instrs  the code snippet to study
      ** @param trace   trace flag
      **/
     InterferenceGraph (const std::string &name,
                        const assem::instrs_t& instrs, bool trace = false);

or

     /// \brief Construct an InterferenceGraph.
     /// \param name    its name, hopefully based on the function name
     /// \param instrs  the code snippet to study
     /// \param trace   trace flag
     InterferenceGraph (const std::string &name,
                        const assem::instrs_t& instrs, bool trace = false);

write

     /** \brief Construct an InterferenceGraph.
         \param name    its name, hopefully based on the function name
         \param instrs  the code snippet to study
         \param trace   trace flag
       */
     InterferenceGraph (const std::string &name,
                        const assem::instrs_t& instrs, bool trace = false);

Of course, Doxygen documentation is not appropriate everywhere.

— Rule: Use foo_get, not get_foo

Accessors have standardized names: foo_get and foo_set.

— Rule: Use rebox.el to markup paragraphs

Often one wants to leave a clear markup to separate different matters. For declarations, this is typically done using the Doxygen \name ... \{ ... \} sequence; for implementation it is advised to use rebox.el (provided in config/) to build them. Once installed (read it for instructions), write a simple comment such as:

          // Comments end with a period.
     

then move your cursor into this comment and press C-u 2 2 3 M-q to get:

          /*-----------------------------.
          | Comments end with a period.  |
          `-----------------------------*/
     

— Rule: Use print as a member function returning a stream

You should always have a means to print a class instance, at least to ease debugging. Use the regular operator<< for standalone printing functions, but print as a member function. Use this kind of prototype:

          std::ostream& Class::print (std::ostream& ostr [, ...]) const
     

where the ellipsis denote optional additional arguments. Note that print returns the stream.