[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Debian coding style?



uwd38znr@umail.furryterror.org (Amy Fong) writes:

      * Compiling: all code must compile clean at warning level 3 with warnings
	as errors.

`gcc -Wall -W -Werror' is what I use for my own code.

   2. Testing: all code must be compilable, tested, and DIFF'ed before being
   checked into source safe. No code should ever be checked in if it will break
   functionality in another part of the program, or if it will break the build.

This isn't exactly what we do in unstable branches of programs.  We
only try to do this in `stable' branches--i.e., where only bug fixes
are allowed.

   All code must be tested by the developer before being checked in. This
   includes walking through the code using a debugger and forcing error
   conditions to make sure that all code paths have been tested. Remember that
   the person who is most qualified to test any piece of code is the person who
   wrote it.

This is a good idea, but we don't enforce testing.  I do recommend it.

   3. Tabs should be set to 2, and they should be kept as tabs, no spaces
   please.

2-character tabs?  That will break all standard Unix utilities.

   4. Code width: The complete line of code should be visible without having to
   scroll horizontally - i.e. it should normally not pass the 78th column.

Fine with me.  Although I use a 132-column screen, I do the same thing.

   5. Naming conventions:

   a) Class names always start with upper-case 'C', followed by an upper-case
   letter, followed by mixed upper/lower case and must always take the form of
   a descriptive noun.

   eg. class CPhoneBookEntry

GNU style prefers phone_book_entry over this camelcapped style.

   b) Method/function names always start with upper-case followed by mixed
   upper/lower case and must always take the form of a descriptive verb or
   action.

   eg. void CPhoneBookEntry::GetUserName();

void phone_book_entry::get_user_name().

   c) Variable names must use hungarian notation (see below) followed by
   upper-case followed with mixed upper/lower case and must always take the
   form of a descriptive noun. Variables which are members of a class must have
   m_ prepended to the name.

   eg. int nUsageCount;

   char* m_pstrUserName;


   Hungarian Notation:

    m_           member variable
    ch           char
    n            int, unsigned int
    s            short, unsigned short
    l            long
    u            unsigned
    b            bool
    d            double
    f            float
    a            array of
    str, sz      any string (str preferred for new code)
    e            enumerated type
    id           integer ID of a control, resource, etc.
    p            pointer to
    c, o         generic C++ object
    h            handle
    k            constant value
    g            global

I don't like Hungarian notation.  I haven't ever seen anyone use it
outside of Windows-specific code.

      * Magic numbers must not be embedded directly in the source code. Use a
	const int variable to hold the magic number rather than a #define.

Good.

   7. Comments : Please comment your code, it makes everyone's life easier.
   Comment major

   blocks of code explaining what you are about to do (or expect to do). Pay
   special attention to cases where the code was written a specific way to work
   around a problem, etc. Don't be afraid to be verbose, but please make sure
   that whatever comments you use really do add value. Remember that comments
   are not a replacement for well written and easily understood code. Rather,
   they are meant to augment the code by detailing information which may not be
   immediately apparent by looking at the code.

[...]

GNU standards recommend capitalizing the first letter of a sentence in
comments and ending sentences with a period.  I prefer this style,
too.

Also, please always use C-style /* */ comments in header files that
can be included in a C program, since otherwise a C compiler can't
read them, only a C++ compiler can.

   8. File level comments are to be included in all source and header files.
   Module name, author, a general description of the code or class contained in
   the file, and a copyright notice should be included as per the sample below.
   The leading and trailing lines (with all the asterisks) should be 78
   characters long to serve as a reference ruler for gauging the length of code
   lines.


   //****************************************************************************
   //
   // Module: mntlist.h
   //
   // Author: Andy Bounsall
   //
   // Description: definition of class CFccMountList which maintains a list of
   // CFccMountItems representing all mountable branches of the
   // file system.
   //
   // Copyright 1998 Corel Computer Corp. All rights reserved.
   //
   //****************************************************************************

I deleted spurious newlines above

The correponding GNU comment is something like this:

/* PSPP - computes sample statistics.
   Copyright (C) 1997, 1998 Free Software Foundation, Inc.
   Written by Ben Pfaff <blp@gnu.org>.

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA. */


   9. Function level comments are to be included for all functions/methods.
   Function/method name and a general description of the purpose of the
   function should be included as per the sample below. The leading and
   trailing lines (with all the asterisks) should be 78 characters long to
   serve as a reference ruler for gauging the length of code lines.


   //***************************************************************************
   //
   // Method: OpenCamera()
   //
   // Purpose: Tries to open a device driver and, if successful, sends an
   // OPEN_CAMERA IOCTL request to initialize the device with the
   // desired video mode.
   //
   //***************************************************************************

GNU recommends not naming the function in the comment.  After all,
unless the comment is really long, you should be able to see the
function and the comment at the same time.  In my opinion, the above
is too wasteful of vertical space.

Corresponding GNU comment:

/* Tries to open a device driver and, if successful, sends an
   OPEN_CAMERA IOCTL request to initialize the device with the desired
   video mode. */

   10. Function/method size: bigger is not better. Functions and methods should
   be kept to a maximum of 40-50 lines. Larger methods should be broken down
   into several smaller methods.

I hope that's not a strict rule.  Sometimes functions must be large.
It's a good principle though.

   11. Curly braces

[...I'm not even going to touch that holy war...]

   13. Assertions and debug only code should be used liberally to check for
   validity of all pointers; range/value validation of function and method
   parameters; assumed states, conditions, etc., etc. The assert() macro is
   your friend - make use of it to validate assumptions, but don't try to use
   it as a replacement for handling runtime errors. (If you're not sure how to
   properly use assertions, please ask your PL). The assert() macro compiles to
   nothing in Release builds (i.e. when NDEBUG is undefined). Debug code other
   than these macros should be bracketed within #ifndef NDEBUG ... #endif
   conditionals so that it is excluded from Release builds.

Sounds good.

   14. Compilation conditionals, with the exception of debug code noted above,
   should be avoided since they make the source code difficult to read and
   maintain. Old or unwanted code should be deleted from the source files prior
   to check-in. Source safes history feature can be used to retrieve an old
   version of the file if the old code is ever required again.

Okay.

   15. Duplicate blocks of code should be avoided. If the same code is needed
   in more than one location, place it in a separate function and call it from
   where ever it's needed.

Yes.

   16. Goto statements should not be used.

Sometimes they're helpful.  Do a Dejanews search on comp.lang.c to
find out why; I'm a regular there, and you should be able to find me
defending their use in certain cases that come up from time to time.

   17. Return: functions and methods should be structured to have a single
   return.

Ugh.  Same as 16.

   18. Switch statements must always handle the default: case. If all expected
   cases have otherwise been handled, the default: case should force an
   assertion failure.

Good, this is my style too.

   Case statements should be indented by 1 tab and separated
   from each other by 1 blank line. Code within each case should be kept to a
   minimum - i.e. call a function from the case statement if more than a few
   lines of code are needed.

Not touching that.

   19. Comparisons for equality against a constant value should list the
   constant value first. Its easy to miss one of the equals signs - this way
   the compiler will catch it if you do.

   eg. if (-1 == m_nResult) rather than if (m_nResult == -1)

I thought you turned up the warning level on your compiler anyway?  It
should catch things like that for you.

   20. Header files must not include other header files (to prevent header file
   bloat). Use forward class references to inform compiler of required data
   types.

I don't like that rule; it's too strict.  Nested headers are useful
sometimes, although they're not always advisable.

   21. Filenames: source files should have .cpp extension. Header files should
   have a .h extension.

Most Debian source code is written in C, not C++.  Much Debian C++
code has .cc extension, not .cpp.

   All filenames should be created using only lower case
   characters. All filenames in #include statements should also be
   written in lower case. Source and header files should normally
   reside in the same directory. Large projects should be split up
   into smaller sub-projects to keep the number of source files in
   each directory manageable.

Good practice.

   22. Localization: text which will be visible to the user should never be
   embedded within the source code. All string literals should be placed in a
   separate header file to ease the pain of possible future translation.

That is not the Unix style.  Unix is a multi-user OS, and users expect
to be able to choose their preferred language at runtime.  Using the
above technique would force the program to be recompiled to change the
language choice.

Instead, Unix software uses runtime substitution of string literals to
do translations, using an internationalization library.  Often, this
just means that instead of writing
	printf ("This is some text to be i18n'd.\n");
you must write
	printf (_("This is some text to be i18n'd.\n");
where _(...) is a call into the internationalization library.

   [...C++ stuff...]

I'm not a C++ expert so I'll let those comments slide.

   26. const modifier is to be used where ever possible, for pointer/reference
   parameters and return values and for methods which do not modify the class.

Yes, good.  gcc has an option to give string literals const char *
type, which can be useful.

   [...more C++ stuff...]

You should take a look at the GNU Coding Standards.  I think that
others have given you pointers to them, so I won't tell you again.

Thanks,

Ben.


Reply to: