Wiki Home

Sample Coding Standards Statement


Namespace: SoftwareEng
A place to show a sample coding standards statement. This is just a sample standard, so don't waste too much time questioning or correcting individual prescriptions. Rather, help by adding prescriptions so this document is as complete as possible.

Abbreviations

Do not abbreviate keywords (even if the language “allows” you to abbreviate) in code.

White space
Use horizontal white space (i.e., spaces) between operators, operands, etc. to separate the components of commands and expressions.

Personally, I find blank spaces between all operators and lowercase keywords makes the code a lot harder to read. I would write the code that follows as:

  DO WHILE LEN(lcLine) > 0
     lnSpace = AT(' ', lcLine)
  etc....

Of course, coding conventions are a bit like religion - everyone has their own opinions. I'd say pick a convention that works for you, and stick with it. Consistency is probably more important, overall. -- Paul Mrozowski

Agreed. It seems sometimes that many people feel that since some white space is desirable, more should be better, and a whole ton of it should really make your code look great. But like all good things, too much is not a good thing - Ed Leafe

To be honest I prefer ALL white space, but was over-ruled. :-) Seriously, I prefer the extra whitespace in expressions because it makes it a bit easier to navigate through the code using the ctrl-left and ctrl-right arrow keys. -- ?jMM

jMM I see where you are going here, No Code = No Bugs

Use vertical white space (i.e., blank lines) to separate groups of statements and delineate sections of code. Use the following rules:
All code blocks within a loop or a branch consisting of more than a single line must begin and end with a blank line. Follow the end of a loop or a branch with two blank lines. Separate dissimilar statements with a blank line.
For example:

do while len( lcLine ) > 0
  lnSpace = at( ' ' , lcLine )

  if lnSpace > 0
    lcWord = left( lcLine , lnSpace - 1 )
  else
    lcWord = alltrim( lcLine )
  endif
	
	
  lcLine = alltrim( subst( lcLine , len( lcWord ) + 1 ) )
  lnWordCnt = lnWordCnt + 1
	
  if alen( laWords , 1 ) < lnWordCnt
    declare laWords[ lnWordCnt ]
  endif
	
  laWords[ lnWordCnt ] = lcWord
	
enddo




Case

Use Capital letters (all UPPERCASE) for constants

Example:

MAX_VALUE 10

Why is Hungarian notation applied only to some things, and not to others? Why not include a scope and type? D (for #define) or C (for Constant) and dnMaxValue? -- Mike Yearwood

Use all lower case for the following:

Commands set help to
File Names buttons.vcx
Keywords browse
Paths c:\windows

When to use Camel (mixed) Case

Use Initial letters (ProperCase) for the following:

Events getFocus
Methods writeExpression
Objects oEmployee
Properties allowRowSizing
Procedures getNextId

Note: The initial character should always be in lowercase and if the name consists of more than one word, the initial-capital words are concatenated.

Comments
While the importance of properly documenting work cannot be over emphasized, it is important to properly comment code in order to get the expected benefits. First of all, realize that a comment is no different than any other programming statement. Once it is created, it has to be maintained and since a comment is not a functional part of the code, it is the last thing to be changed, if changed at all. Comments are not inherently good and if incorrect can be detrimental.
When the time comes to document your code try to answer the following questions:

What does the code do?
In general, nothing documents what code does better than the code itself. Therefore, be careful when adding comments that describe what the code does. These types of comments can be helpful when the code is difficult to read or understand. But if the code is difficult to read or understand you should also think about the possibility that it should be rewritten in a clearer more readable way.
Also, these types of comments are subject to becoming obsolete quickly as the code changes with time.

I still have a tendency to put a one line comment above each block of code giving a general discription of what the code does. It really makes it easier for me to find the section of code I'm interested in without have to interpret the code. I read English much better than VFP code - but I do leave the specifics of "what" to the code itself, unless it's really involved. -- Paul Mrozowski

Why was the code written?
This is probably the most useful type of comment. Every piece of code has a purpose and every piece of code should have a comment that explains that purpose. Sometimes the purpose is due to a business need, in other times the purpose is purely technical.
Typically, the purpose of a routine is constant no matter how many different ways are used to implement the purpose. This makes these types of comments much more stable.
If a routine has multiple purposes it is a good candidate for splitting into separate routines.

How does the code work?
This is similar but slightly different and more useful than the “What” type of comment. In this type you are trying explain in a general sense how the code meets the purpose of the routine. These types of comment only need to change when a different approach to implementation is tried.

I like to follow this rule of thumb when it comes to comments Don't Tell Me What You're Doing, Tell Me Why your Doing It. When explaining the Why, I tried to keep the mindset of What would somebody new to VFP need to know if they had to revise this? So my comments typically go to the degree of explaining that I'm doing a workaround (if applicable), or why I didn't use a more simplified approached. This practice has paid off tremendously for me, especially in the wake of the VS6 SP3 fixes that alleviated the need for certain workarounds. Roxanne Seibert

I like to start my programming by writing pseudo code that maps out the entire routine. This is then block commented and the actual code is written around the comments. So I guess I work opposite to what was stated above about writing the comments last as I tend to write them first. Jim BoothOffsite link to http://www.jamesbooth.com

I've started using an idea I picked up from someone around here: using NEEDS WORK as a keyword. When I get out the once-a-year code I've written I can check for the loose ends with CTRL + F.

Program Logs
Every program, form or report should log its execution to a log file located in the Logs directory. The log should contain any and all information necessary to determine whether the program executed properly.
And there should be a way to turn them off when you don't need the logs ;-) -- Paul Mrozowski

Assertions
All situations where an error could occur as the result of a programmer error should be asserted in the code using the VFP ASSERT command and the code should be tested with ASSERTS set ON to trap for these conditions.

Runtime Errors
For situations where errors occur at runtime that cannot be avoided the code should trap for the specific error using the VFP error handling features. Preferably this would be done using the error method of an object.

VFP Errors
An application level error handler should be used to trap all errors and respond to the error according to its type and severity. This would typically be implemented using the VFP ON ERROR command.

Application Errors
The are situations where a routine reaches a point where it cannot continue and must abort processing. In these situations the routine should generate a user defined error condition. Then test for continued existence of the condition before aborting. This allows a subclasses error method or an error handler to trap the error and resolve the error condition without changing the code.

Outline-style Comments
I have started to format my comments in the following outline style. I find that it helps me think, besides the documentation benefit. Yes, sometimes I have to renumber by hand, but usually it's worth it. AlejandroSosa

For example:

PROCEDURE SomeReport

   * 1. Setup
      * 1.1 Open files
         IF !USED('xxx')
            USE xxx IN 0
         ENDIF
         etc...
         SELECT xxx

      * 1.2 Some other step

   * 2. Get user input
      * 2.1 Date
         ldEndingDate = GetDate()

      * 2.2 Client range
         blah, blah ...

   * 3. Select the data
      SELECT * ;
        FROM yyy ;
       WHERE .... ;
        INTO CURSOR zzz

   * 4. Print report
      = Report('rHistory')

   * 5. Cleanup
      close files, etc...

RETURN



Why not get a life and stop whining about different coding conventions . The manuals that come with the product provide good examples. The beautify function can impose a coding standard without too much effort. I don't have a coding standard because I constantly have to adopt someone elses. Its a big waste of time to roll your own. The real issue here is to avoid conflict with the religious fanatics. Just imagine what would happen if 2 fanatics got assigned to a project. Honestly, its first come first serve. Be open minded and accept the foibles of other programmers.
Don't let anyone write their code too weirdly and we should all be able to live with it.
However, if you like tabs and the other guy uses spaces to indent, you can use the Find and Replace function to fix it. Just find \t and replace it with __. Mike Yearwood

When working in a multi-developer shop, having standards is extremely important. Pick up Code Complete by Steve McConnell and you'll find several references to studies that show coding standards improve all aspects of code development. I've found that by forcing myself to adhere to a standard, that my coding has improved and it's easier to read code that I wrote a year ago.- Craig Berntson

Or you can use a trick I saw in FoxPro Advisor by I believe Christof Wollenhaupt. Ctrl-X to cut. _cliptext = strtran(_cliptext,space(X),chr(9)) where X is the number of spaces you like for your Tabs. Ctrl-V to paste.
No discussion about Fox coding standards would be complete without a mention of proper 'emming', that is, prefixing references to memory variables with 'm.' where necessary. This is something that otherwise pretty experienced Fox programmers tend to forget until they get bitten, and even then they often manage to not get it right (except to the extent that it makes the current problem go away). Some lightyears ago the makers of Fox decreed that table fields would preempt memory variables whenever a matching table field exists; in my eyes this was the worst possible decision (Clipper showed how to do it right) but that is how Fox works and we have no choice in the matter.

It was dBase that first set the standard that table fields would take precendece over memory variables, not Fox. Besides I don't agree that Clipper "got it right"; Clipper did it differently and it was not any more "right" or "wrong". The issue is that one has to know what the rules are and then to code for them as they are and not waste a lot of time discussing how they "should" be. Jim BoothOffsite link to http://www.jamesbooth.com

Amen to that Jim BoothOffsite link to http://www.jamesbooth.com
-- Mike Yearwood

With regard to emming, a coding standard has four options:
(1) simply ignore the problem (i.e. the Microsoft Way)
(2) demand unconditional emming
(3) demand emming where necessary
(4) demand emming where necessary except for THIS, THISFORM and THISFORMSET, coupled with a decree that these three names are never, ever to be used as alias names

Obviously, I tend to favour the fourth option because it strikes a nice balance between safety, required effort and required expertise. Equally obviously, option 2 is by far the easiest of the sensible options because it does not require coders to know when it is necessary to m. and when not.

The reason why I prefer emming over hoping that there won't be a problem is simple: when I write a piece of code I have complete control over emming but in general I do not have any control whatsoever over the field names of a table that might be open in the current work area while the code executes, and only pretty limited control over the alias names of any tables that might be open in the current data session. Emmed code stays written but un-emmed code could blow up any time, even years after it was written. -- Sherlog

Except for arrays, which can mostly be M&Med but sometimes can't. forgive me for forgetting when they can't, but you get a syntax error right away. -- ?cfk

If a team is following a naming convention for variables and fields then emming is redundant and not necessary. If I am coding on a project I following a naming convention that protects against name collisions. IF I am writing utility code that I don't know where it may be used or by whom, then I emm by little heart out. Jim BoothOffsite link to http://www.jamesbooth.com

Better safe than sorry. Even with naming conventions, mistakes happen. Ever have to import a DBF from outside your system? What happens when its field names and types conflict with your memvars? Mdot lets the compiler avoid colisions, something no convention does.

However, here's something I don't get. If I want to add mdots on your team, why on earth would you prevent me?

Also why code differently just because the utility may be used in some strange place? There is also value in coding the same *all* the time. -- Mike Yearwood

See Essential MDot -- Mike Yearwood
http://www.jwz.org/doc/tabs-vs-spaces.html An attempt to introduce some facts and practicality into one of those arguments that just never goes away.
Category Standards And Conventions
( Topic last updated: 2006.08.16 03:07:14 PM )