?? standards.texi
字號:
@exampledo @{ a = foo (a); @}while (a > 0);@end examplePlease use formfeed characters (control-L) to divide the program intopages at logical places (but not within a function). It does not matterjust how long the pages are, since they do not have to fit on a printedpage. The formfeeds should appear alone on lines by themselves.@node Comments@section Commenting Your WorkEvery program should start with a comment saying briefly what it is for.Example: @samp{fmt - filter for simple filling of text}.Please write the comments in a GNU program in English, because Englishis the one language that nearly all programmers in all countries canread. If you do not write English well, please write comments inEnglish as well as you can, then ask other people to help rewrite them.If you can't write comments in English, please find someone to work withyou and translate your comments into English.Please put a comment on each function saying what the function does,what sorts of arguments it gets, and what the possible values ofarguments mean and are used for. It is not necessary to duplicate inwords the meaning of the C argument declarations, if a C type is beingused in its customary fashion. If there is anything nonstandard aboutits use (such as an argument of type @code{char *} which is really theaddress of the second character of a string, not the first), or anypossible values that would not work the way one would expect (such as,that strings containing newlines are not guaranteed to work), be sureto say so.Also explain the significance of the return value, if there is one.Please put two spaces after the end of a sentence in your comments, sothat the Emacs sentence commands will work. Also, please writecomplete sentences and capitalize the first word. If a lower-caseidentifier comes at the beginning of a sentence, don't capitalize it!Changing the spelling makes it a different identifier. If you don'tlike starting a sentence with a lower case letter, write the sentencedifferently (e.g., ``The identifier lower-case is @dots{}'').The comment on a function is much clearer if you use the argumentnames to speak about the argument values. The variable name itselfshould be lower case, but write it in upper case when you are speakingabout the value rather than the variable itself. Thus, ``the inodenumber NODE_NUM'' rather than ``an inode''.There is usually no purpose in restating the name of the function inthe comment before it, because the reader can see that for himself.There might be an exception when the comment is so long that the functionitself would be off the bottom of the screen.There should be a comment on each static variable as well, like this:@example/* Nonzero means truncate lines in the display; zero means continue them. */int truncate_lines;@end exampleEvery @samp{#endif} should have a comment, except in the case of shortconditionals (just a few lines) that are not nested. The comment shouldstate the condition of the conditional that is ending, @emph{includingits sense}. @samp{#else} should have a comment describing the condition@emph{and sense} of the code that follows. For example:@example@group#ifdef foo @dots{}#else /* not foo */ @dots{}#endif /* not foo */@end group@group#ifdef foo @dots{}#endif /* foo */@end group@end example@noindentbut, by contrast, write the comments this way for a @samp{#ifndef}:@example@group#ifndef foo @dots{}#else /* foo */ @dots{}#endif /* foo */@end group@group#ifndef foo @dots{}#endif /* not foo */@end group@end example@node Syntactic Conventions@section Clean Use of C ConstructsPlease explicitly declare all arguments to functions.Don't omit them just because they are @code{int}s.Declarations of external functions and functions to appear later in thesource file should all go in one place near the beginning of the file(somewhere before the first function definition in the file), or elseshould go in a header file. Don't put @code{extern} declarations insidefunctions.It used to be common practice to use the same local variables (withnames like @code{tem}) over and over for different values within onefunction. Instead of doing this, it is better declare a separate localvariable for each distinct purpose, and give it a name which ismeaningful. This not only makes programs easier to understand, it alsofacilitates optimization by good compilers. You can also move thedeclaration of each local variable into the smallest scope that includesall its uses. This makes the program even cleaner.Don't use local variables or parameters that shadow global identifiers.Don't declare multiple variables in one declaration that spans lines.Start a new declaration on each line, instead. For example, insteadof this:@example@groupint foo, bar;@end group@end example@noindentwrite either this:@exampleint foo, bar;@end example@noindentor this:@exampleint foo;int bar;@end example@noindent(If they are global variables, each should have a comment preceding itanyway.)When you have an @code{if}-@code{else} statement nested in another@code{if} statement, always put braces around the @code{if}-@code{else}.Thus, never write like this:@exampleif (foo) if (bar) win (); else lose ();@end example@noindentalways like this:@exampleif (foo) @{ if (bar) win (); else lose (); @}@end exampleIf you have an @code{if} statement nested inside of an @code{else}statement, either write @code{else if} on one line, like this,@exampleif (foo) @dots{}else if (bar) @dots{}@end example@noindentwith its @code{then}-part indented like the preceding @code{then}-part,or write the nested @code{if} within braces like this:@exampleif (foo) @dots{}else @{ if (bar) @dots{} @}@end exampleDon't declare both a structure tag and variables or typedefs in thesame declaration. Instead, declare the structure tag separatelyand then use it to declare the variables or typedefs.Try to avoid assignments inside @code{if}-conditions. For example,don't write this:@exampleif ((foo = (char *) malloc (sizeof *foo)) == 0) fatal ("virtual memory exhausted");@end example@noindentinstead, write this:@examplefoo = (char *) malloc (sizeof *foo);if (foo == 0) fatal ("virtual memory exhausted");@end exampleDon't make the program ugly to placate @code{lint}. Please don't insert anycasts to @code{void}. Zero without a cast is perfectly fine as a nullpointer constant, except when calling a varargs function.@node Names@section Naming Variables and FunctionsThe names of global variables and functions in a program serve ascomments of a sort. So don't choose terse names---instead, look fornames that give useful information about the meaning of the variable orfunction. In a GNU program, names should be English, like othercomments.Local variable names can be shorter, because they are used only withinone context, where (presumably) comments explain their purpose.Please use underscores to separate words in a name, so that the Emacsword commands can be useful within them. Stick to lower case; reserveupper case for macros and @code{enum} constants, and for name-prefixesthat follow a uniform convention.For example, you should use names like @code{ignore_space_change_flag};don't use names like @code{iCantReadThis}.Variables that indicate whether command-line options have beenspecified should be named after the meaning of the option, not afterthe option-letter. A comment should state both the exact meaning ofthe option and its letter. For example,@example@group/* Ignore changes in horizontal whitespace (-b). */int ignore_space_change_flag;@end group@end exampleWhen you want to define names with constant integer values, use@code{enum} rather than @samp{#define}. GDB knows about enumerationconstants.Use file names of 14 characters or less, to avoid creating gratuitousproblems on older System V systems. You can use the program@code{doschk} to test for this. @code{doschk} also tests for potentialname conflicts if the files were loaded onto an MS-DOS filesystem---something you may or may not care about.@node System Portability@section Portability between System TypesIn the Unix world, ``portability'' refers to porting to different Unixversions. For a GNU program, this kind of portability is desirable, butnot paramount.The primary purpose of GNU software is to run on top of the GNU kernel,compiled with the GNU C compiler, on various types of @sc{cpu}. Theamount and kinds of variation among GNU systems on different @sc{cpu}swill be comparable to the variation among Linux-based GNU systems oramong BSD systems today. So the kinds of portability that are absolutelynecessary are quite limited.But many users do run GNU software on non-GNU Unix or Unix-like systems.So supporting a variety of Unix-like systems is desirable, although notparamount.The easiest way to achieve portability to most Unix-like systems is touse Autoconf. It's unlikely that your program needs to know moreinformation about the host platform than Autoconf can provide, simplybecause most of the programs that need such knowledge have already beenwritten.Avoid using the format of semi-internal data bases (e.g., directories)when there is a higher-level alternative (@code{readdir}).As for systems that are not like Unix, such as MSDOS, Windows, theMacintosh, VMS, and MVS, supporting them is usually so much work that itis better if you don't.The planned GNU kernel is not finished yet, but you can tell whichfacilities it will provide by looking at the GNU C Library Manual. TheGNU kernel is based on Mach, so the features of Mach will also beavailable. However, if you use Mach features, you'll probably havetrouble debugging your program today.@node CPU Portability@section Portability between @sc{cpu}sEven GNU systems will differ because of differences among @sc{cpu}types---for example, difference in byte ordering and alignmentrequirements. It is absolutely essential to handle these differences.However, don't make any effort to cater to the possibility that an@code{int} will be less than 32 bits. We don't support 16-bit machinesin GNU.Don't assume that the address of an @code{int} object is also theaddress of its least-significant byte. This is false on big-endianmachines. Thus, don't make the following mistake:@exampleint c;@dots{}while ((c = getchar()) != EOF) write(file_descriptor, &c, 1);@end exampleWhen calling functions, you need not worry about the difference betweenpointers of various types, or between pointers and integers. On mostmachines, there's no difference anyway. As for the few machines wherethere is a difference, all of them support @sc{ansi} C, so you can useprototypes (conditionalized to be active only in @sc{ansi} C) to makethe code work on those systems.In certain cases, it is ok to pass integer and pointer argumentsindiscriminately to the same function, and use no prototype on anysystem. For example, many GNU programs have error-reporting functionsthat pass their arguments along to @code{printf} and friends:@exampleerror (s, a1, a2, a3) char *s; int a1, a2, a3;@{ fprintf (stderr, "error: "); fprintf (stderr, s, a1, a2, a3);@}@end example@noindentIn practice, this works on all machines, and it is much simpler than any``correct'' alternative. Be sure @emph{not} to use a prototypefor such functions.However, avoid casting pointers to integers unless you really need to.These assumptions really reduce portability, and in most programs theyare easy to avoid. In the cases where casting pointers to integers isessential---such as, a Lisp interpreter which stores type information aswell as an address in one word---it is ok to do so, but you'll have tomake explicit provisions to handle different word sizes.@node System Functions@section Calling System FunctionsC implementations differ substantially. @sc{ansi} C reduces but does noteliminate the incompatibilities; meanwhile, many users wish to compileGNU software with pre-@sc{ansi} compilers. This chapter givesrecommendations for how to use the more or less standard C libraryfunctions to avoid unnecessary loss of portability.@itemize @bullet@itemDon't use the value of @code{sprintf}. It returns the number ofcharacters written on some systems, but not on all systems.@item@code{main} should be declared to return type @code{int}. It shouldterminate either by calling @code{exit} or by returning the integerstatus code; make sure it cannot ever return an undefined value.@itemDon't declare system functions explicitly.Almost any declaration for a system function is wrong on some system.To minimize conflicts, leave it to the system header files to declaresystem functions. If the headers don't declare a function, let itremain undeclared.While it may seem unclean to use a function without declaring it, inpractice this works fine for most system library functions on thesystems where this really happens; thus, the disadvantage is onlytheoretical. By contrast, actual declarations have frequently causedactual conflicts.@itemIf you must declare a system function, don't specify the argument types.Use an old-style declaration, not an @sc{ansi} prototype. The more youspecify about the function, the more likely a conflict.@itemIn particular, don't unconditionally declare @code{malloc} or@code{realloc}.Most GNU programs use those functions just once, in functionsconventionally named @code{xmalloc} and @code{xrealloc}. Thesefunctions call @code{malloc} and @code{realloc}, respectively, andcheck the results.Because @code{xmalloc} and @code{xrealloc} are defined in your program,you can declare them in other files without any risk of type conflict.On most systems, @code{int} is the same length as a pointer; thus, thecalls to @code{malloc} and @code{realloc} work fine. For the fewexceptional systems (mostly 64-bit machines), you can use@strong{conditionalized} declarations of @code{malloc} and@code{realloc}---or put these declarations in configuration filesspecific to those systems.@itemThe string functions require special treatment. Some Unix systems havea header file @file{string.h}; others have @file{strings.h}. Neitherfile name is portable. There are two things you can do: use Autoconf tofigure out which file to include, or don't include either file.@itemIf you don't include either strings file, you can't get declarations forthe string functions from the header file in the usual way.That causes less of a problem than you might think. The newer @sc{ansi}string functions should be avoided anyway because many systems stilldon't support them. The string functions you can use are these:@examplestrcpy strncpy strcat strncatstrlen strcmp strncmpstrchr strrchr@end exampleThe copy and concatenate functions work fine without a declaration aslong as you don't use their values. Using their values without adeclaration fails on systems where the width of a pointer differs fromthe width of @code{int}, and perhaps in other cases. It is trivial toavoid using their values, so do that.The compare functions and @code{strlen} work fine without a declarationon most systems, possibly all the ones that GNU software runs on.You may find it necessary to declare them @strong{conditionally} on afew systems.The search functions must be declared to return @code{char *}. Luckily,there is no variation in the data type they return. But there isvariation in their names. Some systems give these functions the names@code{index} and @code{rindex}; other systems use the names@code{strchr} and @code{strrchr}. Some systems support both pairs ofnames, but neither pair works on all systems.You should pick a single pair of names and use it throughout yourprogram. (Nowadays, it is better to choose @code{strchr} and@code{strrchr} for new programs, since those are the standard @sc{ansi}names.) Declare both of those names as functions returning @code{char*}. On systems which don't support those names, define them as macrosin terms of the other pair. For example, here is what to put at thebeginning of your file (or in a header) if you want to use the names@code{strchr} and @code{strrchr} through
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -