| \input texinfo @c -*-texinfo-*- |
| @c %**start of header |
| @c oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo |
| @c o |
| @c GNAT DOCUMENTATION o |
| @c o |
| @c G N A T C O D I N G S T Y L E o |
| @c o |
| @c $Revision: 1.4 $ |
| @c o |
| @c Copyright (C) 1992-2001 Ada Core Technologies, Inc. o |
| @c o |
| @c GNAT is free software; you can redistribute it and/or modify it under o |
| @c terms of the GNU General Public License as published by the Free Soft- o |
| @c ware Foundation; either version 2, or (at your option) any later ver- o |
| @c sion. GNAT is distributed in the hope that it will be useful, but WITH- o |
| @c OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY o |
| @c or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License o |
| @c for more details. You should have received a copy of the GNU General o |
| @c Public License distributed with GNAT; see file COPYING. If not, write o |
| @c to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, o |
| @c MA 02111-1307, USA. o |
| @c o |
| @c oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo |
| |
| @setfilename gnat-style.info |
| @settitle GNAT Coding Style |
| @dircategory Programming |
| @direntry |
| * gnat-style: (gnat-style). GNAT Coding Style |
| @end direntry |
| |
| @macro syntax{element} |
| @t{\element\} |
| @end macro |
| @c %**end of header |
| |
| @ifinfo |
| @center GNAT Coding Style |
| |
| @center A guide for GNAT developers |
| Copyright (C) 1992-2001 Ada Core Technologies, Inc. |
| @end ifinfo |
| |
| @titlepage |
| @sp 10 |
| @title GNAT Coding Style |
| @subtitle A guide for GNAT developers |
| @subtitle Document revision level $Revision: 1.4 $ |
| @author Ada Core Technologies, Inc. |
| @end titlepage |
| @raisesections |
| |
| @node Top, General, , (dir) |
| @comment node-name, next, previous, up |
| |
| @menu |
| * General:: |
| * Lexical Elements:: |
| * Declarations and Types:: |
| * Expressions and Names:: |
| * Statements:: |
| * Subprograms:: |
| * Packages:: |
| * Program Structure:: |
| @end menu |
| |
| @c ------------------------------------------------------------------------- |
| @node General, Lexical Elements, Top, Top |
| @section General |
| @c ------------------------------------------------------------------------- |
| |
| @noindent |
| Most of GNAT is written in Ada using a consistent style to ensure |
| readability of the code. This document has been written to help |
| maintain this consistent style, while having a large group of developers |
| work on the compiler. |
| |
| @noindent |
| For the coding style in the C parts of the compiler and run time, |
| see the GNU Coding Guidelines. |
| |
| @noindent |
| This document is structured after the Ada Reference manual. |
| Those familiar with that document should be able to quickly |
| lookup style rules for particular constructs. |
| |
| @c ------------------------------------------------------------------------- |
| @node Lexical Elements, Declarations and Types, General, Top |
| @section Lexical Elements |
| @c ------------------------------------------------------------------------- |
| |
| @subsection Character Set and Separators |
| @c ------------------------------------------------------------------------- |
| |
| @itemize @bullet |
| @item |
| The character set used should be plain 7-bit ASCII@. |
| The only separators allowed are space and the end-of-line sequence. |
| No other control character or format effector (such as HT, VT, FF) |
| should be used. |
| The normal end-of-line sequence is used, which may be LF, CR/LF or CR, |
| depending on the host system. An optional SUB (16#1A#) may be present as the |
| last character in the file on hosts using that character as file terminator. |
| |
| @item |
| Files that are checked in or distributed should be in host format. |
| |
| @item |
| A line should never be longer than 79 characters, not counting the line |
| separator. |
| |
| @item |
| Lines must not have trailing blanks. |
| |
| @item |
| Indentation is 3 characters per level for if statements, loops, case |
| statements. For exact information on required spacing between lexical |
| elements, see file @file{style.adb}. |
| |
| @end itemize |
| |
| @subsection Identifiers |
| @c ------------------------------------------------------------------------- |
| @itemize @bullet |
| @item |
| Identifiers will start with an upper case letter, and each letter following |
| an underscore will be upper case. Short acronyms may be all upper case. |
| All other letters are lower case. |
| An exception is for identifiers matching a foreign language. In particular, |
| we use all lower case where appropriate for C@. |
| |
| @item |
| Use underscores to separate words in an identifier. |
| |
| @item Try to limit your use of abbreviations in identifiers. |
| It is ok to make a few abbreviations, explain what they mean, and then |
| use them frequently, but don't use lots of obscure abbreviations. An |
| example is the @code{ALI} word which stands for Ada Library |
| Information and is by convention always written in upper-case when |
| used in entity names. |
| |
| @smallexample |
| procedure Find_ALI_Files; |
| @end smallexample |
| |
| @item |
| Don't use the variable @samp{I}, use @samp{J} instead, @samp{I} is too |
| easily mixed up with @samp{1} in some fonts. Similarly don't use the |
| variable @samp{O}, which is too easily mixed up with @samp{0}. |
| @end itemize |
| |
| @subsection Numeric Literals |
| @c ------------------------------------------------------------------------- |
| @itemize @bullet |
| @item |
| Numeric literals should include underscores where helpful for |
| readability. |
| |
| @smallexample |
| 1_000_000 |
| 16#8000_000# |
| 3.14159_26535_89793_23846 |
| @end smallexample |
| @end itemize |
| |
| @subsection Reserved Words |
| @c ------------------------------------------------------------------------- |
| @itemize @bullet |
| @item |
| Reserved words use all lower case. |
| |
| @smallexample |
| return else |
| @end smallexample |
| |
| @item |
| The words @samp{Access}, @samp{Delta} and @samp{Digits} are |
| capitalized when used as @syntax{attribute_designator}. |
| @end itemize |
| |
| @subsection Comments |
| @c ------------------------------------------------------------------------- |
| |
| @itemize @bullet |
| @item |
| Comment start with @samp{-- } (i.e.@: @samp{--} followed by two spaces). |
| The only exception to this rule (i.e.@: one space is tolerated) is when the |
| comment ends with @samp{ --}. |
| It also accepted to have only one space between @samp{--} and the start |
| of the comment when the comment is at the end of a line, |
| after some Ada code. |
| |
| @item |
| Every sentence in a comment should start with an upper-case letter (including |
| the first letter of the comment). |
| |
| @item |
| When declarations are commented with ``hanging'' comments, i.e.@: |
| comments after the declaration, there is no blank line before the |
| comment, and if it is absolutely necessary to have blank lines within |
| the comments these blank lines @emph{do} have a @samp{--} (unlike the |
| normal rule, which is to use entirely blank lines for separating |
| comment paragraphs). The comment start at same level of indentation |
| as code they are commenting. |
| |
| @smallexample |
| z : Integer; |
| -- @r{Integer value for storing value of} z |
| -- |
| -- @r{The previous line was a blank line.} |
| @end smallexample |
| |
| @item |
| Comments that are dubious or incomplete or comment on possibly |
| wrong or incomplete code should be preceded or followed by @samp{???}@. |
| |
| @item |
| Comments in a subprogram body must generally be surrounded by blank lines, |
| except after a @samp{begin}: |
| |
| @smallexample |
| begin |
| -- @r{Comment for the next statement} |
| |
| A := 5; |
| |
| -- @r{Comment for the B statement} |
| |
| B := 6; |
| @end smallexample |
| |
| @item |
| In sequences of statements, comments at the end of the lines should be |
| aligned. |
| |
| @smallexample |
| My_Identifier := 5; -- @r{First comment} |
| Other_Id := 6; -- @r{Second comment} |
| @end smallexample |
| |
| @item |
| Short comments that fit on a single line are @emph{not} ended with a |
| period. Comments taking more than a line are punctuated in the normal |
| manner. |
| |
| @item |
| Comments should focus on why instead of what. |
| Descriptions of what subprograms do go with the specification. |
| |
| @item |
| Comments describing a subprogram spec should specifically mention the |
| formal argument names. General rule: write a comment that does not |
| depend on the names of things. The names are supplementary, not |
| sufficient, as comments. |
| |
| @item |
| Do NOT put two spaces after periods in comments. |
| @end itemize |
| |
| @c ------------------------------------------------------------------------- |
| @node Declarations and Types, Expressions and Names, Lexical Elements,Top |
| @section Declarations and Types |
| @c ------------------------------------------------------------------------- |
| |
| @itemize @bullet |
| @item |
| In entity declarations, colons must be surrounded by spaces. Colons |
| should be aligned. |
| |
| @smallexample |
| Entity1 : Integer; |
| My_Entity : Integer; |
| @end smallexample |
| |
| @item |
| Declarations should be grouped in a logical order. |
| Related groups of declarations may be preceded by a header comment. |
| |
| @item |
| All local subprograms in a subprogram or package body should be declared |
| before the first local subprogram body. |
| |
| @item |
| Don't declare local entities that hide global entities. |
| |
| @item |
| Don't declare multiple variables in one declaration that spans lines. |
| Start a new declaration on each line, instead. |
| |
| @item |
| The @syntax{defining_identifier}s of global declarations serve as |
| comments of a sort. So don't choose terse names, but look for names |
| that give useful information instead. |
| |
| @item |
| Local names can be shorter, because they are used only within |
| one context, where comments explain their purpose. |
| |
| @end itemize |
| |
| |
| @c ------------------------------------------------------------------------- |
| @node Expressions and Names, Statements, Declarations and Types, Top |
| @section Expressions and Names |
| @c ------------------------------------------------------------------------- |
| |
| @itemize @bullet |
| |
| @item |
| Every operator must be surrounded by spaces, except for the |
| exponentiation operator. |
| |
| @smallexample |
| E := A * B**2 + 3 * (C - D); |
| @end smallexample |
| |
| @item |
| When folding a long line, fold before an operator, not after. |
| |
| @item |
| Use parentheses where they make the intended order of evaluation clearer: |
| @smallexample |
| (A / B) * C |
| @end smallexample |
| @end itemize |
| |
| @c ------------------------------------------------------------------------- |
| @node Statements, Subprograms, Expressions and Names, Top |
| @section Statements |
| @c ------------------------------------------------------------------------- |
| |
| @subsection Simple and Compound Statements |
| @c ------------------------------------------------------------------------- |
| @itemize @bullet |
| @item |
| Use only one statement or label per line. |
| @item |
| A longer @syntax{sequence_of_statements} may be divided in logical |
| groups or separated from surrounding code using a blank line. |
| @end itemize |
| |
| @subsection If Statements |
| @c ------------------------------------------------------------------------- |
| @itemize @bullet |
| @item |
| When the @samp{if}, @samp{elsif} or @samp{else} keywords fit on the |
| same line with the condition and the @samp{then} keyword, then the |
| statement is formatted as follows: |
| |
| @smallexample |
| if @var{condition} then |
| ... |
| elsif @var{condition} then |
| ... |
| else |
| ... |
| end if; |
| @end smallexample |
| |
| @noindent |
| When the above layout is not possible, @samp{then} should be aligned |
| with @samp{if}, and conditions should preferably be split before an |
| @samp{and} or @samp{or} keyword a follows: |
| |
| @smallexample |
| if @var{long_condition_that_has_to_be_split} |
| and then @var{continued_on_the_next_line} |
| then |
| ... |
| end if; |
| @end smallexample |
| |
| @noindent |
| The @samp{elsif}, @samp{else} and @samp{end if} always line up with |
| the @samp{if} keyword. The preferred location for splitting the line |
| is before @samp{and} or @samp{or}. The continuation of a condition is |
| indented with two spaces or as many as needed to make nesting clear. |
| As exception, if conditions are closely related either of the |
| following is allowed: |
| |
| @smallexample |
| if x = lakdsjfhlkashfdlkflkdsalkhfsalkdhflkjdsahf |
| or else |
| x = asldkjhalkdsjfhhfd |
| or else |
| x = asdfadsfadsf |
| then |
| |
| if x = lakdsjfhlkashfdlkflkdsalkhfsalkdhflkjdsahf or else |
| x = asldkjhalkdsjfhhfd or else |
| x = asdfadsfadsf |
| then |
| @end smallexample |
| |
| @item |
| Conditions should use short-circuit forms (@samp{and then}, |
| @samp{or else}). |
| |
| @item |
| Complex conditions in if statements are indented two characters: |
| |
| @smallexample |
| if @var{this_complex_condition} |
| and then @var{that_other_one} |
| and then @var{one_last_one} |
| then |
| ... |
| @end smallexample |
| |
| @item |
| Every @samp{if} block is preceded and followed by a blank line, except |
| where it begins or ends a @syntax{sequence_of_statements}. |
| |
| @smallexample |
| A := 5; |
| |
| if A = 5 then |
| null; |
| end if; |
| |
| A := 6; |
| @end smallexample |
| @end itemize |
| |
| @subsection Case Statements |
| @itemize @bullet |
| |
| @item |
| Layout is as below. For long case statements, the extra indentation |
| can be saved by aligning the when clauses with the opening case. |
| |
| @smallexample |
| case @var{expression} is |
| when @var{condition} => |
| ... |
| when @var{condition} => |
| ... |
| end case; |
| @end smallexample |
| @end itemize |
| |
| @subsection Loop Statements |
| @itemize @bullet |
| |
| @noindent |
| When possible, have @samp{for} or @samp{while} on one line with the |
| condition and the @samp{loop} keyword. |
| |
| @smallexample |
| for J in S'Range loop |
| ... |
| end loop; |
| @end smallexample |
| |
| @noindent |
| If the condition is too long, split the condition (see ``If |
| statements'' above) and align @samp{loop} with the @samp{for} or |
| @samp{while} keyword. |
| |
| @smallexample |
| while @var{long_condition_that_has_to_be_split} |
| and then @var{continued_on_the_next_line} |
| loop |
| ... |
| end loop; |
| @end smallexample |
| |
| @noindent |
| If the @syntax{loop_statement} has an identifier, it is laid out as follows: |
| |
| @smallexample |
| Outer : while not @var{condition} loop |
| ... |
| end Outer; |
| @end smallexample |
| @end itemize |
| |
| @subsection Block Statements |
| @itemize @bullet |
| |
| @item |
| The @samp{declare} (optional), @samp{begin} and @samp{end} statements |
| are aligned, except when the @syntax{block_statement} is named. There |
| is a blank line before the @samp{begin} keyword: |
| |
| @smallexample |
| Some_Block : declare |
| ... |
| |
| begin |
| ... |
| end Some_Block; |
| @end smallexample |
| |
| @end itemize |
| |
| @c ------------------------------------------------------------------------- |
| @node Subprograms, Packages, Statements, Top |
| @section Subprograms |
| @c ------------------------------------------------------------------------- |
| |
| |
| @subsection Subprogram Declarations |
| @c ------------------------------------------------------------------------- |
| @itemize @bullet |
| |
| @item |
| Do not write the @samp{in} for parameters, especially in functions: |
| |
| @smallexample |
| function Length (S : String) return Integer; |
| @end smallexample |
| |
| @item |
| When the declaration line for a procedure or a function is too long, fold it. |
| In this case, align the colons, and, for functions, the result type. |
| |
| @smallexample |
| function Head |
| (Source : String; |
| Count : Natural; |
| Pad : Character := Space) |
| return String; |
| @end smallexample |
| |
| @item |
| The parameter list for a subprogram is preceded by a space: |
| |
| @smallexample |
| procedure Func (A : Integer); |
| @end smallexample |
| |
| @end itemize |
| |
| @subsection Subprogram Bodies |
| @c ------------------------------------------------------------------------- |
| @itemize @bullet |
| |
| @item |
| The functions and procedures should always be sorted alphabetically in |
| a compilation unit. |
| |
| @item |
| All subprograms have a header giving the function name, with the following |
| format: |
| |
| @smallexample |
| ----------------- |
| -- My_Function -- |
| ----------------- |
| |
| procedure My_Function is |
| begin |
| @end smallexample |
| |
| Note that the name in the header is preceded by a single space, |
| not two spaces as for other comments. |
| |
| @item |
| Every subprogram body must have a preceding @syntax{subprogram_declaration}. |
| |
| @item |
| If there any declarations in a subprogram, the @samp{begin} keyword is |
| preceded by a blank line. |
| |
| @item |
| If the declarations in a subprogram contain at least one nested |
| subprogram body, then just before the of the enclosing subprogram |
| @samp{begin}, there is a line: |
| |
| @smallexample |
| -- @r{Start of processing for @var{Enclosing_Subprogram}} |
| |
| begin |
| @end smallexample |
| |
| @end itemize |
| |
| @c ------------------------------------------------------------------------- |
| @node Packages, Program Structure, Subprograms, Top |
| @section Packages and Visibility Rules |
| @c ------------------------------------------------------------------------- |
| |
| @itemize @bullet |
| |
| @item |
| All program units and subprograms have their name at the end: |
| |
| @smallexample |
| package P is |
| ... |
| end P; |
| @end smallexample |
| |
| @item |
| We will use the style of @samp{use}-ing @samp{with}-ed packages, with |
| the context clauses looking like: |
| |
| @smallexample |
| with A; use A; |
| with B; use B; |
| @end smallexample |
| |
| @item |
| Names declared in the visible part of packages should be |
| unique, to prevent name clashes when the packages are @samp{use}d. |
| |
| @smallexample |
| package Entity is |
| type Entity_Kind is ...; |
| ... |
| end Entity; |
| @end smallexample |
| |
| @item |
| After the file header comment, the context clause and unit specification |
| should be the first thing in a @syntax{program_unit}. |
| @end itemize |
| |
| @c ------------------------------------------------------------------------- |
| @node Program Structure,, Packages, Top |
| @section Program Structure and Compilation Issues |
| @c ------------------------------------------------------------------------- |
| |
| @itemize @bullet |
| @item |
| Every GNAT source file must be compiled with the @option{-gnatg} |
| switch to check the coding style (Note that you should look at |
| @file{style.adb} to see the lexical rules enforced by |
| @option{-gnatg}). |
| |
| @item |
| Each source file should contain only one compilation unit. |
| |
| @item |
| Filenames should be 8 characters or less followed by the @samp{.adb} |
| extension for a body or @samp{.ads} for a spec. |
| |
| @item |
| Unit names should be distinct when krunched to 8 characters |
| (see @file{krunch.ads}) and the filenames should match the unit name, |
| except that they are all lower case. |
| @end itemize |
| |
| @bye |