AppendixC.pdf

(436 KB) Pobierz
Programming Style Guidelines
HLA Programming Style Guidelines
C.1
Introduction
Appendix C
Most people consider assembly language programs difficult to read. While there are a multitude of rea-
sons why people feel this way, the primary reason is that assembly language does not make it easy for pro-
grammers to write readable programs. This doesn’t mean it’s impossible to write readable programs, only
that it takes an extra effort on the part of an assembly language programmer to produce readable code.
One of the design goals of the High Level Assembler (HLA) was to make it possible for assembly lan-
guage programmers to write readable assembly language programs. Nevertheless, without discipline, pande-
monium will result in any program of any decent size. Even if you adhere to a fixed set of style guidelines,
others may still have trouble reading and understanding your code. Equally important to following a set of
style guidelines is that you following a generally accepted set of style guidelines; guidelines that others are
familiar and agree with. The purpose of this appendix, written by the designer of the HLA language, is to
provide a consistent set of guidelines that HLA programmers can use consistently. Unless you can show a
good reason to violate these rules, you should following them carefully when writing HLA programs; other
HLA programmers will thank you for this.
C.1.1 Intended Audience
Of course, an assembly language program is going to be nearly unreadable to someone who doesn’t
know assembly language. This is true for almost any programming language. Other than burying a tutorial
on 80x86 assembly language in a program’s comments, there is no way to address this problem
1
other than
to assume that the reader is familiar with assembly language programming and specifically HLA.
In view of the above, it makes sense to define an "intended audience" that we intend to have read our
assembly language programs. Such a person should:
Be a reasonably competent 80x86 assembly language/HLA programmer.
Be reasonably familiar with the problem the assembly language program is attempting to
solve.
Fluently read English
2
.
Have a good grasp of high level language concepts.
Possess appropriate knowledge for someone working in the field of Computer Science (e.g.,
understands standard algorithms and data structures, understands basic machine architecture,
and understands basic discrete mathematics).
C.1.2 Readability Metrics
One has to ask "What is it that makes one program more readable than another?" In other words, how
do we measure the "readability" of a program? The usual metric, "I know a well-written program when I see
one" is inappropriate; for most people, this translates to "If your programs look like my better programs
then they are readable, otherwise they are not." Obviously, such a metric is of little value since it changes
with every person.
To develop a metric for measuring the readability of an assembly language program, the first thing we
must ask is "Why is readability important?" This question has a simple (though somewhat flippant) answer:
1. Doing so (inserting an 80x86 tutorial into your comments) would wind up making the program
less
readable to those who
already know assembly language since, at the very least, they’d have to skip over this material; at the worst they’d have to
read it (wasting their time).
2. Or whatever other natural language is in use at the site(s) where you develop, maintain, and use the software.
Beta Draft - Do not distribute
© 2001, By Randall Hyde
Page 1411
Appendix C
Appendices
Readability is important because programs are
read
(furthermore, a line of code is typically read ten times
more often than it is written). To expand on this, consider the fact that most programs are read and main-
tained by other programmers (Steve McConnell claims that up to ten generations of maintenance program-
mers work on a typical real world program before it is rewritten from scratch; furthermore, they spend up to
60% of their effort on that code simply figuring out how it works). The more readable your programs are,
the less time these other people will have to spend figuring out what your program does. Instead, they can
concentrate on adding features or correcting defects in the code.
For the purposes of this document, we will define a "readable" program as one that has the following
trait:
A "readable" program is one that a competent programmer (one who is familiar with the prob-
lem the program is attempting to solve) can pick up, without ever having seen the program
before, and fully comprehend the entire program in a minimal amount of time.
That’s a tall order! This definition doesn’t sound very difficult to achieve, but few non-trivial programs
ever really achieve this status. This definition suggests that an appropriate programmer (i.e., one who is
familiar with the problem the program is trying to solve) can pick up a program, read it at their normal read-
ing pace (just once), and fully comprehend the program. Anything less is not a "readable" program.
Of course, in practice, this definition is unusable since very few programs reach this goal. Part of the
problem is that programs tend to be quite long and few human beings are capable of managing a large num-
ber of details in their head at one time. Furthermore, no matter how well-written a program may be, "a com-
petent programmer" does not suggest that the programmer’s IQ is so high they can read a statement a fully
comprehend its meaning without expending much thought. Therefore, we must define readability, not as a
boolean entity, but as a scale. Although truly unreadable programs exist, there are many "readable" pro-
grams that are less readable than other programs. Therefore, perhaps the following definition is more realis-
tic:
A readable program is one that consists of one or more
modules.
A competent program should
be able to pick a given module in that program and achieve an 80% comprehension level by
expending no more than an average of one minute for each statement in the program.
An 80% comprehension level means that the programmer can correct bugs in the program and add new
features to the program without making mistakes due to a misunderstanding of the code at hand.
C.1.3 How to Achieve Readability
The "I’ll know one when I see one" metric for readable programs provides a big hint concerning how
one should write programs that are readable. As pointed out early, the "I’ll know it when I see it" metric sug-
gests that an individual will consider a program to be readable if it is very similar to (good) programs that
this particular person has written. This suggests an important trait that readable programs must possess:
consistency. If all programmers were to write programs using a consistent style, they’d find programs writ-
ten by others to be similar to their own, and, therefore, easier to read. This single goal is the primary purpose
of this appendix - to suggest a consistent standard that everyone will follow.
Of course, consistency by itself is not good enough. Consistently bad programs are not particularly
easy to read. Therefore, one must carefully consider the guidelines to use when defining an all-encompass-
ing standard. The purpose of this paper is to create such a standard. However, don’t get the impression that
the material appearing in this document appears simply because it sounded good at the time or because of
some personal preferences. The material in this paper comes from several software engineering texts on the
subject (including Elements of Programming Style, Code Complete, and Writing Solid Code), nearly 20
years of personal assembly language programming experience, and research that led to the development of a
set of generic programming guidelines for industrial use.
This document assumes consistent usage by its readers. Therefore, it concentrates on a lot of mechani-
cal and psychological issues that affect the readability of a program. For example, uppercase letters are
harder to read than lower case letters (this is a well-known result from psychology research). It takes longer
Page 1412
© 2001, By Randall Hyde
Beta Draft - Do not distribute
Programming Style Guidelines
for a human being to recognize uppercase characters, therefore, an average human being will take more time
to read text written all in upper case. Hence, this document suggests that one should avoid the use of upper-
case sequences in a program. Many of the other issues appearing in this document are in a similar vein; they
suggest minor changes to the way you might write your programs that make it easier for someone to recog-
nize some pattern in your code, thus aiding in comprehension.
C.1.4 How This Document is Organized
This document follows a top-down discussion of readability. It starts with the concept of a program.
Then it discusses modules. From there it works its way down to procedures. Then it talks about individual
statements. Beyond that, it talks about components that make up statements (e.g., instructions, names, and
operators). Finally, this paper concludes by discussing some orthogonal issues.
Section Two discusses programs in general. It primarily discusses documentation that must accompany
a program and the organization of source files. It also discusses, briefly, configuration management and
source code control issues. Keep in mind that figuring out how to build a program (make, assemble, link,
test, debug, etc.) is important. If your reader fully understands the "heapsort" algorithm you are using, but
cannot build an executable module to run, they still do not fully understand your program.
Section Three discusses how to organize modules in your program in a logical fashion. This makes it
easier for others to locate sections of code and organizes related sections of code together so someone can
easily find important code and ignore unimportant or unrelated code while attempting to understand what
your program does.
Section Four discusses the use of procedures within a program. This is a continuation of the theme in
Section Three, although at a lower, more detailed, level.
Section Five discusses the program at the level of the statement. This (large) section provides the meat
of this proposal. Most of the rules this paper presents appear in this section.
Section Six discusses comments and other documentation appearing within the source code.
Section Seven discusses those items that make up a statement (labels, names, instructions, operands,
operators, etc.) This is another large section that presents a large number of rules one should follow when
writing readable programs. This section discusses naming conventions, appropriateness of operators, and so
on.
Section Eight discusses data types and other related topics.
C.1.5 Guidelines, Rules, Enforced Rules, and Exceptions
Not all rules are equally important. For example, a rule that you check the spelling of all the words in
your comments is probably less important than suggesting that the comments all be in English
3
. Therefore,
this paper uses three designations to keep things straight: Guidelines, Rules, and Enforced Rules.
A Guideline is a suggestion. It is a rule you should follow unless you can verbally defend why you
should break the rule. As long as there is a good, defensible, reason, you should feel no apprehension vio-
lated a guideline. Guidelines exist in order to encourage consistency in areas where there are no good rea-
sons for choosing one methodology over another. You shouldn’t violate a Guideline just because you don’t
like it -- doing so will make your programs inconsistent with respect to other programs that do follow the
Guideline (and, therefore, harder to read), however, you shouldn’t lose any sleep because you violated a
Guideline.
Rules are much stronger than Guidelines. You should never break a rule unless there is some external
reason for doing so (e.g., making a call to a library routine forces you to use a bad naming convention).
Whenever you feel you must violate a rule, you should verify that it is reasonable to do so in a peer review
with at least two peers. Furthermore, you should explain in the program’s comments why it was necessary
3. You may substitute the local language in your area if it is not English.
Beta Draft - Do not distribute
© 2001, By Randall Hyde
Page 1413
Appendix C
Appendices
to violate the rule. Rules are just that -- rules to be followed. However, there are certain situations where it
may be necessary to violate the rule in order to satisfy external requirements or even make the program more
readable.
Enforced Rules are the toughest of the lot. You should
never
violate an enforced rule. If there is ever a
true need to do this, then you should consider demoting the Enforced Rule to a simple Rule rather than treat-
ing the violation as a reasonable alternative.
An Exception is exactly that, a known example where one would commonly violate a Guideline, Rule,
or (very rarely) Enforced Rule. Although exceptions are rare, the old adage "Every rule has its exceptions..."
certainly applies to this document. The Exceptions point out some of the common violations one might
expect.
Of course, the categorization of Guidelines, Rules, Enforced Rules, and Exceptions herein is one man’s
opinion. At some organizations, this categorization may require reworking depending on the needs of that
organization.
C.1.6 Source Language Concerns
This document will assume that the entire program is written in 80x86 assembly language using the
HLA assembler/compiler. Although this organization is rare in commercial applications, this assumption
will, in no way, invalidate these guidelines. Other guidelines exist for various high level languages (includ-
ing a set written by this paper’s author). You should adopt a reasonable set of guidelines for the other lan-
guages you use and apply these guidelines to the 80x86 assembly language modules in the program.
C.2
Program Organization
A source program generally consists of one or more source, object, and library files. As a project gets
larger and the number of files increases, it becomes difficult to keep track of the files in a project. This is
especially true if a number of different projects share a common set of source modules. This section will
address these concerns.
C.2.1 Library Functions
A library, by its very nature, suggests stability. Ignoring the possibility of software defects, one would
rarely expect the number or function of routines in a library to vary from project to project. A good example
is the "HLA Standard Library." One would expect "stdout.put" to behave identically in two different pro-
grams that use the Standard Library. Contrast this against two programs, each of which implement their own
version of
stdout.put.
One could not reasonably assume both programs have identical implementations
4
.
This leads to the following rule:
Rule:
Library functions are those routines intended for common reuse in many different assembly
language programs. All assembly language (callable) libraries on a system should exist as
".lib" files and should appear in a "\lib" or "\hlalib" subdirectory.
"\hlalib" is probably a better choice if you’re using multiple languages since those other lan-
guages may need to put files in a "\lib" directory.
It’s probably reasonable to leave the HLA Standard Library’s "hlalib.lib" file in the "\hla\hla-
lib" directory since most people expect it there.
Guideline:
Exception:
4. In fact, just the opposite is true. One should get concerned if both implementations
are
identical. This would suggest poor
planning on the part of the program’s author(s) since the same routine must now be maintained in two different programs.
Page 1414
© 2001, By Randall Hyde
Beta Draft - Do not distribute
Programming Style Guidelines
The rule above ensures that the library files are all in one location so they are easy to find, modify, and
review. By putting all your library modules into a single directory, you avoid configuration management
problems such as having outdated versions of a library linking with one program and up-to-date versions
linking with other programs.
C.2.2 Common Object Modules
This document defines a
library
as a collection of object modules that have wide application in many
different programs. The HLA Standard Library is a typical example of a library. Some object modules are
not so general purpose, but still find application in two or more different programs. Two major configuration
management problems exist in this situation: (1) making sure the ".obj" file is up-to-date when linking it
with a program; (2) Knowing which modules use the module so one can verify that changes to the module
won’t break existing code.
The following rules takes care of case one:
Rule:
If two different program share an object module, then the associated source, object, and make-
files for that module should appear in a subdirectory that is specific to that module (i.e., no
other files in the subdirectory). The subdirectory name should be the same as the module
name. If possible, you should create a set of link/alias/shortcuts to this subdirectory and place
these links in the main directory of each of the projects that utilize the module. If links are not
possible, you should place the module’s subdirectory in a "\common" subdirectory.
Every subdirectory containing one or more modules should have a make file that will automat-
ically generate the appropriate, up-to-date, ".obj" files. An individual, a batch file, or another
make file should be able to automatically generate new object modules (if necessary) by sim-
ply executing the make program.
Use Microsoft’s nmake program. At the very least, use nmake acceptable syntax in your make-
files.
Enforced Rule:
Guideline:
The other problem, noting which projects use a given module is much more difficult. The obvious solu-
tion, commenting the source code associated with the module to tell the reader which programs use the mod-
ule, is impractical. Maintaining these comments is too error-prone and the comments will quickly get out of
phase and be worse than useless -- they would be incorrect. A better solution is to create alias and place this
alias in the main subdirectory of each program that links the module.
Guideline:
If a project uses a module that is not local to the project’s subdirectory, create an alias to the file
in the project’s subdirectory. This makes locating the file very easy.
C.2.3 Local Modules
Local modules are those that a single program/project uses. Typically, the source and object code for
each module appears in the same directory as the other files associated with the project. This is a reasonable
arrangement until the number of files increases to the point that it is difficult to find a file in a directory list-
ing. At that point, most programmers begin reorganizing their directory by creating subdirectories to hold
many of these source modules. However, the placement, name, and contents of these new subdirectories can
have a big impact on the overall readability of the program. This section will address these issues.
The first issue to consider is the contents of these new subdirectories. Since programmers rummaging
through this project in the future will need to easily locate source files in a project, it is important that you
organize these new subdirectories so that it is easy to find the source files you are moving into them. The
best organization is to put each source module (or a small group of
strongly related
modules) into its own
subdirectory. The subdirectory should bear the name of the source module minus its suffix (or the main
module if there is more than one present in the subdirectory). If you place two or more source files in the
same directory, ensure this set of source files forms a
cohesive
set (meaning the source files contain code
that solve a single problem). A discussion of cohesiveness appears later in this document.
Beta Draft - Do not distribute
© 2001, By Randall Hyde
Page 1415
Zgłoś jeśli naruszono regulamin