Ada Quality and Style: Guidelines for Professional Programmers SPC-91061-N VERSION 02.00.02 1991 SOFTWARE PRODUCTIVITY CONSORTIUM Ada Quality and Style: Guidelines for Professional Programmers SPC-91061-N VERSION 02.00.02 1991 Software Productivity Consortium SPC Building 2214 Rock Hill Road Herndon, Virginia 22070-4005 Copyright E 1989, 1991 Software Productivity Consortium, Inc., Herndon, Virginia. Permission to use, copy, modify and distribute this documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appears in all copies and that both this copyright notice and this permission notice appear in supporting documentation, and that the name Software Productivity Consortium, Inc. not be used in advertising or publicity pertaining to distribution of the guidelines without specific, written prior permission. Software Productivity Consortium, Inc. makes no representations about the suitability of the guidelines described herein for any purpose. It is provided "as is" without express or implied warranty. PREFACE The second edition has been produced to correct, clarify, update and enhance various topics in the original version. The book has undergone minor restructuring. While the chapters remain the same, some of the sections have been rearranged for clarity. Also, instantiations have been included within relevant sections. In some sections, there is an additional subsection on automation. While there have been changes, additions and deletions to the guidelines, the major conceptual changes have been in the following areas: use of the others clause in case statements, use of while loops and blocks, exception handling, anonymous task types, and conditional and timed entry calls. The sections on comments and the chapter on reuse have been expanded. Additionally, some examples have been enhanced. We invite comments on this guidebook to continue enhancing its quality and usefulness. We will consider suggestions for current guidelines as well as areas for future expansion. Examples that highlight particular points are most helpful. Please direct comments to: Technology Transfer Division - AQS Software Productivity Consortium SPC Building 2214 Rock Hill Road Herndon, Virginia 22070-4005 (703) 742-7211 Please fill out and mail the registration form at the back of this document to receive updates and other information. AUTHORS AND ACKNOWLEDGEMENTS The authors for the second edition are Kent Johnson, Elisa Simmons, and Fred Stluka. Contributors are Alex Blakemore and Robert Hofkin. Reviewers include Alex Blakemore, Rick Conn, Tim Harrison, Dave Nettles, and Doug Smith. Additional support has been provided by Vicki Clatterbuck, Leslie Hubbard, and Debra Morgan. The following people contributed to an instantiation of the first edition's guidelines: Rich Bechtold, Pete Bloodgood, Shawna Gregory, Tim Powell, Dave Nettles, Kevin Schaan, Doug Smith and Perry Tsacoumis. Special thanks are extended to Loral for providing feedback in the form of their Software Productivity Laboratory Ada Standards. The Consortium would also like to acknowledge those involved in the first edition. The authors were Richard Drake, Samuel Gregory, Margaret Skalko, and Lyn Uzzle. Managing the project was Paul Cohen. The contributors and reviewers were Mark Dowson, John Knight, Henry Ledgard, and Robert Mathis. Word processing was performed by Debra Morgan. Additional supporters included Bruce Barnes, Alex Blakemore, Terry Bollinger, Charles Brown, Neil Burkhard, William Carlson, Susan Carroll, John Chludzinski, Vicki Clatterbuck, Robert Cohen, Elizabeth Comer, Daniel Cooper, Jorge Diaz-Herrera, Tim Harrison, Robert Hofkin, Allan Jaworski, Edward Jones, John A.N. Lee, Eric Marshall, Charles Mooney, John Moore, Karl Nyberg, Arthur Pyster, Samuel Redwine, Jr., William Riddle, Lisa Smith, Fred Stluka, Kathy Velick, David Weiss, and Howard Yudkin. CONTENTS CHAPTER 1 Introduction 1 1.1 HOW TO USE THIS BOOK 2 1.2 TO THE NEW Ada PROGRAMMER 3 1.3 TO THE EXPERIENCED Ada PROGRAMMER 3 1.4 TO THE SOFTWARE PROJECT MANAGER 3 CHAPTER 2 Source Code Presentation 5 2.1 CODE FORMATTING 5 2.2 SUMMARY 15 CHAPTER 3 Readability 17 3.1 SPELLING 17 3.2 NAMING CONVENTIONS 19 3.3 COMMENTS 24 3.4 USING TYPES 36 3.5 SUMMARY 37 CHAPTER 4 Program Structure 41 4.1 HIGH-LEVEL STRUCTURE 41 4.2 VISIBILITY 45 4.3 EXCEPTIONS 50 4.4 SUMMARY 51 CHAPTER 5 Programming Practices 55 5.1 OPTIONAL PARTS OF THE SYNTAX 55 5.2 PARAMETER LISTS 58 5.3 TYPES 62 5.4 DATA STRUCTURES 64 5.5 EXPRESSIONS 66 5.6 STATEMENTS 70 5.7 VISIBILITY 77 5.8 USING EXCEPTIONS 79 5.9 ERRONEOUS EXECUTION 81 5.10 SUMMARY 85 CHAPTER 6 Concurrency 89 6.1 TASKING 89 6.2 COMMUNICATION 94 6.3 TERMINATION 100 6.4 SUMMARY 103 CHAPTER 7 Portability 105 7.1 FUNDAMENTALS 106 7.2 NUMERIC TYPES AND EXPRESSIONS 109 7.3 STORAGE CONTROL 112 7.4 TASKING 113 7.5 EXCEPTIONS 115 7.6 REPRESENTATION CLAUSES AND IMPLEMENTATION-DEPENDENT FEATURES 116 7.7 INPUT/OUTPUT 119 7.8 SUMMARY 120 CHAPTER 8 Reusability 123 8.1 UNDERSTANDING AND CLARITY 124 8.2 ROBUSTNESS 125 8.3 ADAPTABILITY 130 8.4 INDEPENDENCE 140 8.5 SUMMARY 142 CHAPTER 9 Instantiation 145 9.1 HORIZONTAL SPACING 145 9.2 INDENTATION 146 9.3 MORE ON ALIGNMENT 148 9.4 PAGINATION 148 9.5 SOURCE CODE LINE LENGTH 148 9.6 NUMBERS 149 9.7 CAPITALIZATION 149 9.8 FILE HEADERS 149 9.9 PROGRAM UNIT SPECIFICATION HEADER 149 9.10 PROGRAM UNIT BODY HEADER 150 9.11 NAMED ASSOCIATION 150 9.12 ORDER OF PARAMETER DECLARATIONS 151 9.13 NESTING 151 9.14 GLOBAL ASSUMPTIONS 151 CHAPTER 10 Complete Example 153 APPENDIX A - Map from Ada Language Reference Manual to Guidelines 163 REFERENCES 169 BIBLIOGRAPHY 172 INDEX 175 CHAPTER 1 Introduction This book is intended to help the computer professional produce better Ada programs. It presents a set of specific guidelines for using the powerful features of Ada in a disciplined manner. Each guideline consists of a concise statement of the principles that should be followed, and a rationale explaining why following the guideline is important. In most cases, an example of the use of the guideline is provided, and in some cases a further example is included showing the consequences of violating the guideline. Possible exceptions to the application of the guideline are explicitly noted, and further explanatory notes, including notes on how the guideline could be automated by a tool, are provided where appropriate. Many of the guidelines are specific enough to be adopted as corporate or project programming standards. Others require a managerial decision on a particular instantiation before they can be used as standards. In such cases, a sample instantiation is presented and used throughout the examples. Such instantiations should be recognized as weaker recommendations than the guidelines themselves. These issues are discussed in Section 1.4 of this introduction. Other sections of the introduction discuss how this book should be used by various categories of software development personnel. Ada was designed to support the development of high-quality, reliable, reusable, portable software. For a number of reasons, no programming language can ensure the achievement of these desirable objectives on its own. For example, programming must be embedded in a disciplined development process that addresses requirements analysis, design, implementation, verification, validation and maintenance in an organized way. The use of the language must conform to good programming practices based on well established software engineering principles. This book is intended to help bridge the gap between these principles and the actual practice of programming in Ada. Clear, readable, understandable source text eases program evolution, adaptation, and maintenance. First, such source text is more likely to be correct and reliable. Second, effective code adaptation is a prerequisite to code reuse, a technique that has the potential for drastic reductions in system development cost. Easy adaptation requires a thorough understanding of the software, this is facilitated considerably by clarity. Finally, since maintenance (really evolution) is a costly process that continues throughout the life of a system, clarity plays a major role in keeping maintenance costs down. Over the entire life cycle, code has to be read and understood far more often than it is written; the investment of writing readable, understandable code is thus well worthwhile. Many of the guidelines in this book are designed to promote clarity of the source text. There are two main aspects of code clarity. Careful and consistent layout of the source text on the page or the screen can enhance readability dramatically. Similarly, careful attention to the structure of code can make it easier to understand. This is true both on the small scale (e.g., by careful choice of identifier names or by disciplined use of loops), and on the large scale (e.g., by proper use of packages). Both layout and structure are treated by these guidelines. Comments in source text are a controversial issue. There are arguments both for and against the view that comments enhance readability. The biggest problem with comments in practice is that people often fail to update them when the associated source text is changed, thereby making the commentary misleading. Commentary should be minimized and largely reserved for highlighting cases where there are overriding reasons to violate one of the guidelines. If possible, source text should use self-explanatory names for objects and program units, and use simple, understandable program structures so that little additional commentary is needed. The extra effort in selecting (and entering) appropriate names, and the extra thought needed to design clean and understandable program structures are fully justified. Programming texts often fail to discuss overall program structure; Chapter 4 addresses this. The majority of the guidelines in that chapter are concerned with the application of sound software engineering principles such as information hiding and separation of concerns. The chapter is neither a textbook on nor an introduction to these principles; rather it indicates how they can be realized using the features of Ada. A number of other guidelines are particularly concerned with reliability and portability issues. They counsel avoidance of language features and programming practices that either depend on properties not defined in Ada or on properties that may vary from implementation to implementation. Some of these guidelines, such as the one forbidding dependence on expression evaluation order, should never be violated. Others may have to be violated in special situations such as interfacing to other systems. This should only be done after careful deliberation, and such violations should be prominently indicated. Performance constraints are often offered as an excuse for unsafe programming practices; this is rarely a sufficient justification. Software tools could be used to enforce, encourage, or check conformance to many of the guidelines. At present, such tools for Ada primarily consist of code formatters or syntax directed editors. Existing code formatters are often parameterizable and can be instantiated to lay out code in a way consistent with many of the guidelines in this book. This book is intended for those involved in the actual development of software systems written in Ada. Below, discusses how to make the most effective use of the material presented. Readers with different levels of Ada experience and different roles in a software project will need to use the book in different ways. Specific comments to three broad categories of software development personnel are addressed: inexperienced Ada programmers, experienced Ada programmers, and software development managers. 1.1 HOW TO USE THIS BOOK There are a number of ways in which this book can be used: as a reference on good Ada style; as a comprehensive list of guidelines which will contribute to better Ada programs; or as a reference work to consult about using specific features of the language. The book contains many guidelines, some of which are quite complex. Learning them all at the same time should not be necessary; it is unlikely that you will be using all the features of the language at once. However, it is recommended that all programmers (and, where possible, other Ada project staff) make an effort to read and understand Chapters 2, 3, and 4 and Chapter 5 up to Section 5.7. Some of the material is quite difficult (for example, Section 4.2 which discusses visibility) but it covers issues which are fundamental to the effective use of Ada, and is important for any software professional involved in building Ada systems. The remainder of the book covers relatively specific issues. Exceptions and erroneous execution is covered at the end of Chapter 5, and tasking, portability and reuse is covered in Chapters 6, 7, and 8 respectively. You should be aware of the content of this part of the book. You may be required to follow the guidelines presented in it, but you could defer more detailed study until needed. Meanwhile, it can serve as useful reference material about specific Ada features; for example, the discussion of floating point numbers in the chapter on portability. Chapter 9 is directed at software project managers. It repeats those guidelines that need to be instantiated to be used as standards, and indicates the instantiation that has been adopted in the guidelines' examples. Chapter 10 consists of an extended example of an Ada program that conforms to the guidelines presented. This book is not intended as an introductory text on Ada or as a complete manual of the Ada language. It is assumed that you already know the syntax of Ada, and have a rudimentary understanding of the semantics. With such a background, you should find the guidelines useful, informative, and often enlightening. If you are learning Ada you should equip yourself with a comprehensive introduction to the language such as (Barnes 1989) or (Cohen 1986). The Ada Language Reference Manual (Department of Defense 1983) should be regarded as a crucial companion to this book. The majority of guidelines reference the sections of the Ada Language Reference Manual that define the language features being discussed. Appendix A cross references sections of the Ada Language Reference Manual to the guidelines. Throughout the book, references are given to other sources of information about Ada style and other Ada issues. The references are listed at the end of the book, followed by a bibliography which includes them and other relevant sources consulted during the book's preparation. 1.2 TO THE NEW Ada PROGRAMMER At first sight, Ada offers a bewildering variety of features. It is a powerful tool intended to solve difficult problems and almost every feature has a legitimate application in some context. This makes it especially important to use Ada's features in a disciplined and organized way. The guidelines in this book forbid the use of few Ada features. Rather, they show how the features can be systematically deployed to write clear, high-quality programs. Following the guidelines will make learning Ada easier and help you to master its apparent complexity. From the beginning, you can write programs that exploit the best features of the language in the way that the designers intended. Programmers experienced in using another programming language are often tempted to use Ada as if it were their familiar language, but with irritating syntactic differences. This pitfall should be avoided at all costs, it can lead to convoluted code that subverts exactly those aspects of Ada that make it so suitable for building high-quality systems. You must learn to "think Ada"; following the guidelines in this book and reading the examples of their use will help you to do this as quickly and painlessly as possible. To some degree, novice programmers learning Ada have an advantage. Following the guidelines from the beginning helps in developing a clear programming style that effectively exploits the language. If you are in this category, it is recommended that you adopt the guidelines for those exercises you perform as part of learning Ada. Initially, developing sound programming habits by concentrating on the guidelines themselves, and their supporting examples, is more important than understanding the rationale for each guideline. Note that each chapter ends with a summary of the guidelines it contains. 1.3 TO THE EXPERIENCED Ada PROGRAMMER As an experienced programmer you are already writing code that conforms to many of the guidelines in this book. In some areas, however, you may have adopted a personal programming style that differs from that presented here, and you might be reluctant to change. Carefully review those guidelines that are inconsistent with your current style, make sure that you understand their rationale, and consider adopting them. The overall set of guidelines in this book embodies a consistent approach to producing high-quality programs which would be weakened by too many exceptions. Another important reason for general adoption of common guidelines is consistency. If all the staff of a project write source text in the same style, many critical project activities are easier. Consistent code simplifies formal and informal code reviews, system integration, within-project code reuse and the provision and application of supporting tools. In practice, corporate or project standards may require deviations from the guidelines to be explicitly commented, so adopting a nonstandard approach may require extra work. 1.4 TO THE SOFTWARE PROJECT MANAGER Technical management plays a key role in ensuring that the software produced in the course of a project is correct, reliable, maintainable, and portable. Management must create a project-wide commitment to the production of high-quality code; define project-specific coding standards and guidelines; foster an understanding of why uniform adherence to the chosen coding standards is critical to product quality; and establish policies and procedures to check and enforce that adherence. The guidelines contained in this book can aid such an effort. An important activity for managers is the definition of coding standards for a project or organization. These guidelines do not, in themselves, constitute a complete set of standards, but can serve as a basis for them. A number of guidelines indicate a range of decisions, but do not prescribe a particular decision. For example, the second guideline in the book (Guideline 2.1.2) advocates using a consistent number of spaces for indentation, and indicates in the rationale that 2 to 4 spaces would be reasonable. With your senior technical staff, you should review each such guideline and arrive at a decision about its instantiation that will constitute your project or organizational standard. To support this process, Chapter 9 of the book lists all guidelines that need instantiation to be used as standards. It also gives a possible instantiation for each guideline that corresponds to the decision adopted by this book, and used in the extended example of Chapter 10. Two other areas require managerial decisions about standardization. Guideline 3.1.4 advises you to avoid arbitrary abbreviations in object or unit names. You should prepare a glossary of acceptable abbreviations for a project that allows the use of shorter versions of application-specific terms (e.g., FFT for Fast Fourier Transform or SPN for Stochastic Petri Net). You should keep this glossary short and restrict it to terms which need to be used frequently as part of names. Having to refer continually to an extensive glossary to understand source text makes it hard to read. The portability guidelines given in Chapter 7 need careful attention. Adherence to them is important even if the need to port the resulting software is not currently foreseen. Following the guidelines improve the potential reusability of the resulting code in projects that use different Ada implementations. You should insist that when particular project needs force the relaxation of some of the portability guidelines, nonportable features of the source text are prominently indicated. Observing the Chapter 7 guidelines requires definition and standardization of project- or organization-specific numeric types to use in place of the (potentially nonportable) predefined numeric types. Your decisions on standardization issues should be incorporated in a project or organization coding standards document. With coding standards in place, you need to ensure adherence to them. Probably the most important aspect of this is gaining the wholehearted commitment of your programming staff to use them. Given this commitment, and the example of high-quality Ada being produced by your programmers, it will be far easier to conduct effective formal code reviews that check compliance to project standards. Consistent coding standards work well with automatic tool support. If you have a tools group in your project or organization, they can be tasked to acquire or develop tools to support your standards. It is very cost effective to use tools to enforce standards. Where tools cannot be used to automatically modify code to conform to standards, they can often be used to at least check conformance. See the automation notes sections associated with many of the guidelines. Some general issues concerning the management of Ada projects are discussed by (Foreman and Goodenough 1987). CHAPTER 2 Source Code Presentation The physical layout of source text on the page or screen has a strong effect on its readability. This chapter contains source code presentation guidelines intended to make the code more readable. In addition to the general purpose guidelines, specific recommendations are made in the "instantiation" sections. If you disagree with the specific recommendations, you may want to adopt your own set of conventions which still follow the general purpose guidelines. Above all, be consistent across your entire project. An entirely consistent layout is hard to achieve or check manually. Therefore you may prefer to automate layout with a tool for parameterized code formatting, or incorporate the guidelines into an automatic coding template. Beware, however, that such tools are limited. Some of the guidelines and specific recommendations presented in this section cannot be enforced by a formatting tool because they are based on the semantics, not the syntax, of the Ada code. More details are given in the "automation notes" sections below. 2.1 CODE FORMATTING The "code formatting" of Ada source code affects how the code looks, not what the code does. Topics included here are horizontal spacing, indentation, alignment, pagination, and line length. The most important guideline is to be consistent throughout the compilation unit as well as the project. 2.1.1 Horizontal Spacing guideline * Use consistent spacing around delimiters. * Use the same spacing as you would in regular prose. instantiation Specifically, leave at least one blank space in the following places, as shown in the examples throughout this book. More spaces may be required for the vertical alignment recommended in subsequent guidelines. - Before and after the following delimiters and binary operators: + - * / & < = > /= <= >= := => | : <> - Outside of the quotes for string (") and character (') literals, except where prohibited below. - Outside, but not inside, of parentheses. - After commas (,) and semicolons (;). Do not leave any blank spaces in the following places, even if this conflicts with the above recommendation. - After the plus (+) and minus (-) signs when used as unary operators. - Inside of label delimiters (<< >>). - Before and after the following: ' . ** - Between multiple consecutive opening or closing parentheses. - Before commas (,) and semicolons (;). example REGISTER (PC) := REGISTER (A); OPERATOR_PRECEDENCE_MNEMONICS : STRING := "My Dog Ain't Smart," & " but he obeys" & " My Dear Aunt Sallie."; ARRAY_NAME (INDEX) := MEMORY (BASE_ADDRESS + (INDEX * ELEMENT_LENGTH)); GET_NEXT_VALUE (SENSOR); type SIGNED_WHOLE_16 is range -(2**15) .. (2**15) - 1; rationale It is a good idea to use whitespace around delimiters and operators because they are typically short (one or two character) sequences which can easily get lost among the longer keywords and identifiers. Putting whitespace around them makes them stand out. Consistency in spacing also helps by making the source code easier to scan visually. However, many of the delimiters (commas, semicolons, parentheses, etc.) are familiar as normal punctuation marks. It is distracting to see them spaced differently in a computer program than in normal text. Therefore, they should be spaced the same (no spaces before commas and semicolons, no spaces inside of parentheses, etc.). exception The one notable exception to this is the colon (:). In Ada, it is useful to use the colon as a tabulator, or a column separator (see Guideline 2.1.4). In this context, it makes sense to put spaces before and after the colon, rather than only after as in normal text. automation notes The guidelines in this section are easily enforced with an automatic code formatter. 2.1.2 Indentation guideline * Indent and align nested control structures, continuation lines, and embedded units consistently. * Distinguish between indentation for nested control structures and for continuation lines. * Use spaces for indentation, not the tab character (Nissen and Wallis 1984, w2.2). instantiation Specifically, the following indentation conventions are recommended, as shown in the examples throughout this book. Note that the minimum indentation is described. More spaces may be required for the vertical alignment recommended in subsequent guidelines. - Use the recommended paragraphing shown in the Ada Language Reference Manual (Department of Defense 1983). - Use three spaces as the basic unit of indentation for nesting. - Use two spaces as the basic unit of indentation for continuation lines. A label is outdented three spaces. A continuation line is indented two spaces: <