Coding conventions
Just about everyone in the VRL ends up re-using code and programs that someone else wrote previously, and undoubtedly the code that they write will be used by someone else in the future. Therefore the golden rule applies well to software development in our lab: do unto others as you would have them do unto you. This page records best practices for getting started developing software in an environment where code lives on through many generations of researchers.
The primary things to keep in mind are that:
- Future users of your code need read and write permission; and
- Future users of your code can't read your mind, so it must be organized and well-documented.
File Permissions
On Linux, there are three basic permissions that may be modified for a file: r, w, and x, which stand for read, write, and execute. For a given file, the permissions may be different for three different classes of users, u, g, and o, which stand for the user who owns the file, other members of the owner's group, and other users. Therefore there are a total of nine permission bits on each file. Each three-bit rwx code may be represented in binary as a number between 0 and 7:
| # | r | w | x | Permission |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | No access |
| 1 | 0 | 0 | 1 | Execute only |
| 2 | 0 | 1 | 0 | Write only |
| 3 | 0 | 1 | 1 | Write and execute |
| 4 | 1 | 0 | 0 | Read only |
| 5 | 1 | 0 | 1 | Read and execute |
| 6 | 1 | 1 | 0 | Read and write |
| 7 | 1 | 1 | 1 | Read, write, and execute |
The entire set of permissions for a file or directory may therefore be compactly represented by a three-digit octal number. For example, 754 means that the owner may read, write, and execute the file, other members of the owner's group may read and execute it, and all others may only read.
Default permissions for new files
When a new file is created, it starts off having permissions 666 (read and write allowed for all users). For directories, the execute permission means that the user can access the directory, and so the initial permissions on a new directory are 777 (read, write, and access allowed for all users).
These initial permissions are modified by what's called the "umask" or "file mode creation mask". This is a nine-bit binary mask that is XOR'd with the initial permissions. By default, the umask is 022, and therefore a new file will come out with permissions 644 = 666 ^ 022 (read and write for the owner, read only for all others).
Every member of our research group is a member of the graphics group on the CS department network. In order to facilitate code sharing and collaboration, we need to make sure that read and write permissions are set not just for the owner of a file, but for all members of the graphics group, too. This is easily accopmlished by setting the umask to 002 instead: 666 ^ 002 = 664 (read and write for the owner and members of the owner's group, read only for all others).
The umask command either views or sets the current value of the umask. The config file ~/.environment is run every time you open a shell, and the default one created by the CS department for new users sets the umask to 022. To set the umask to 002 at the beginning of every shell session, just edit your ~/.environment file. Look for the line
umask 022
and change it to
umask 002
To make your change take effect immediately, execute the following command in all your open shells:
source ~/.environment
If that gives you an error, try the following instead:
. ~/.environment
You can check that it worked by running umask; the result should be 002. From now on, any files you create from the command line will be writeable by the group.
Commands you should know for dealing with permissions
Type man <command> at the command line to get information about any of the following:
- umask --- view or set the umask
- chmod --- change the permissions for a file or directory
- chown --- change the owner of a file or directory (only allowed if you are the owner)
Development Best Practices
Minimal Coding Standards
- Tabs are only meaningful in your edit session.
Do not use tabs (except in Makefiles as needed). Indent 4 spaces, but 3 is okay if you prefer.
- Name script files with suffixes.
Use Python for scripts (very portable). Avoid reliance on Cygwin.
- Commenting code does not slow progress.
If you make it a habit it speeds things up. At a minimum write a method’s purpose and parameter usage.
- Linux file system links are not portable. Never use them.
Coding in C++
- Use .cpp and .h suffixes for c++ source file names. Not: .C and .H
- Avoid conditional compilation (#ifdef).
- Use brackets around code bodies over multiple lines.
Evil: if (condition)
action;
Good: if (condition) action; if (condition) { action };
if (condition) if (condition)
{ action; {
} action;
}
- Line up brackets so they are easier to match visually.
- Do not #include .cpp files.