




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、GNU 编码标准GNU 编码标准11目的12. 适用范围13. 规范内容11目的规范 GNU 相关项目的代码编写规范。2适用范围适合的 GNU 项目。3规范内容3.1私有程序不要在任何情况下,为你在的 GNU 中的工作或者在工作中代码(或者任何其它私有程序)。Unix 的源如果你对一个 Unix 程序内容有一些模糊的记忆,这并不因为着你绝对写模仿它, 但请试图在不同的代码行来组织它,因为这将使你工作的结果在细节上与 Unix 版本有所不同。例如,Unix 工具通常进行了优化以使用最少的内存;如果你更希望提高速度,你的程序将会有很大的不同。 你可以在内核中保存整个输入文件并计算机源代码编写规范(
2、GNU 编码规范)编号:MPDK/ZY-14-2007修:0号:2007-06-28实施时间:2007-06-28编制:批准:且在内存中扫描而不是使用 stdio。使用比 Unix 程序更新的、 更明智的算法。不使用暂时文件。在一遍扫描而不是两遍扫描中完成任务( 我在assembler(汇编器)中这样做了)。或者相反,强调简单性而不是速度。对于一些应用算机只要使用简单的算法就够了。说,今天的计或者注重一般性。例如,Unix 程序通常使用静态的表格和固定大小的字,这导致了不可改变的限制; 用动态分配来代替。确认你的程序处理了输入文件为空和其它滑稽的情况。为增加扩展性而增加一种 程序语言并且用那种
3、语言完成程序的一个部分。或者把程序的一部分修改成的库。或者用一个简单的废物收集器而不是在内存的时候精确地进行跟踪, 或者使用诸如 obstacks 这样的新的 GNU 工具。3.2 接受他人的奉献如果其他人发给你一段添加到你正在编写的代码,我们需要准许需要从你那里取得同样的法律文书。程序的每使用它的法律文书 -个重要的贡献者都必须签署 某种法律文书以使得我们可以给程序一个清晰的标题。仅有主要作者是不够的。所以,在把来自于他人的任何共享添加到之前,告诉我们以便我们可以做出安排 以获取文书。在你实际地使用贡献之前,请等待直到我们告诉你我们已经收到了签署的文书。这即适用于你前也适用于之后。如果你收到
4、了一个修正bug 的补丁,并且 它们做了主要的修改,我们就需要为他提供法律文书。你不需要为这里或者那里的少数几行修改提供文书,因为对于达到目的没有意义。 还有,如果你从建议中获得的仅仅是一些想法,而不是你实际上使用的代码,你也不需要文书。 例如,如果你写了一个程序的不同解决方案,你并不需要获得文书。我知道这是十分麻烦的;它对我们来说也十分麻烦。但如果你不等待,你就可能误入歧途, 如果这个贡献者的雇主不肯签署弃权可能不得不再次把代码剔除出来!怎么办?你最糟糕的情况是如果你忘记告诉我们其它的贡献者,我们可能会因此而窘迫地出现在上。3.3 修改日志(Change Logs)为每个目录维护一个修改日志
5、,以记述对这个目录下源文件的修改。这样做的目的是使得 在将来寻找 bug 的人可以指导大致是那些修改导致了错误。通常,一个新的 bug 可以在最近进行 的修改中被找到。更重要的事,修改日志有助于消除程序的不同部分之间在概念上的不一致性; 它们可以告诉我们概念产生的历史。使用 Emacs 命令 M-x add-change 在修改日之中创建一个新的条目。一个条目应该 包含一个、被修改的文件的名称以及被扩在括号内的、被修改了的函数、变量或者任何东西。 括号之后是冒号和对你对函数或变量的修改的说明。用空行把无关的条目分隔开。如果两个条目反映了同一个修改,因而它们一同工作,那就不要 在它们之间使用空行
6、。如果后续的条目的是相同的文件,那么你可以忽略文件名的。下面是一些例子:* register.el (insert-register): Return nil.(jump-to-register): Likewise.* sort.el (sort-subr): Return nil.* tex-mode.el (tex-bibtex-file, tex-file, tex-region):Restart the tex shell if process is gone or stopped.(tex-shell-running): New function.* expr.c (store_o
7、ne_arg): Round size up for move_block_to_reg.(expand_call): Round up when emitting USE insns.* stmt.c (assign_parms): Round size up for move_block_from_reg.在这里没有必要叙述修改的完整目录和它们是如何协同工作的。把这些说明作为注到 代码中更好一些。这就是说为什么只要给出“Newfunction”就够了;在源代码中,与函数 放在一起的注释说明了它是做什么的。然而,有时为一大堆修改写上一行文字以描述它们的整体目的是有用的。在概念上,你可以把修改
8、日志看作解释原始版本与当前版本的不同的“undo 列表”。 人们可以阅读当前的版本;他们不需要修改日志告诉他们其中有什么。他们从修改日之中 得到的是关于早期版本的不同的清晰解释。在你以简单的方式修改函数的调用顺序,并且你修改了所有对函数的调用时,不必为所有 的调用创建单独的条目。只要在被调用的函数的条目中写“All callers changed.”即可。在你仅仅修改了注释或者文档字的时候,为该文件写一个条目,而不必提到函数, 就足够了。只要写"Doc fix."。不必为文档文件维护修改日志。这是因为文档不那么容易 受到难以修正的错误的影响。文档不是由那些必须以精确地工程方
9、式相互作用的部分组成的; 要修改一个错误,你不需要知道这个错误的历史。3.4 与其它实现的兼容性作为一个特例,对于 GNU 中的工具程序和库,它们应该和 Berkeley Unix相应的部分向, 如果标准 C 定义了它们的行为,那它们应该和标准 C向,如果 POSIX 规范定义了它们的行为, 那它们也应该与 POSIX 规兼容。当这些标准发生的时候,为每个标准提供兼容模式是有用的。标准 C 和 POSIX把选项 -ansi'或进行的扩展。自由地进行你的扩展,并且patible'包括进来以关闭你的扩展。 但是如果扩展很可能导致任何实际程序或者的,那么它可能实际上不是向上兼容的。
10、尝试一下重新定义它的界面。当一个特征仅仅被用户(而被程序或者命令文件)所使用的时候,并且在 Unix 中它完成得 并不好,请自由地用完全不同并且更好的方式代替它。(例如,用 Emacs 代替 vi。)但同时提供兼容 模式仍然是很好的。(现在有自由的 vi 实现,所以我们提供了它。)欢迎提供 Berkeley Unix 没有提供的有用功能。Unix 中没有的附加功能可能是有用的,但我们 优先那些 Unix 已经有的功能。Makefile 惯例本章叙述为 GNU 程序书写 Makefile 的惯例。Makefile 的通用惯例每个 Makefile 都应该包含这一行:SHELL = /bin/sh
11、以避免那些由从环境中继承 SHELL 变量的系统带来的麻烦。(GNU make永远出现这个问题。)不要假定.'出现在用于寻找可执行令的路径中。当你需要在 make期间运行作为你的 包的一部分的,如果程序是作为 make 的一部分而创建的,请确保它使用了./',或者 如果文件是部分,请确保它使用了$(srcdir)/'。被改变的源代码的一如 果 运 行 configure' 时 使 用 了 选 项 -srcdir' ,那么 ./' 与$(srcdir)/'之间的区别就十分重要。一下形式的规则:foo.1 : foo.man sedscrip
12、tsed -e sedscript foo.man > foo.1将在当前目录不是源代码目录的情况下导致错误,这是因为foo.man'和sedscript' 不在当前目录中。在使用 GNU make 的时候,由于不论源文件在那里,make'的自动变量$<' 都将表示它,所以在只存在一个依赖文件的情况下,依靠VPATH'来寻找源文件仍然是可行的。 (许多版本的 make 只在隐含规则中设置$<'。) 如下的 makefile 目标:foo.o : bar.c$(CC) -I. -I$(srcdir) $(CFLAGS) -c ba
13、r.c -o foo.o将被如下目标所替代:foo.o : bar.c$(CC) $(CFLAGS) $< -o $以便使VPATH'能够正确地工作。当目标含有多的依赖文件时,显式地使用$(srcdir)' 让规则正常工作的最简单办法。例如,上述为foo.1'而提供的目标最好被写作:foo.1 : foo.man sedscriptsed -s $(srcdir)/sedscript $(srcdir)/foo.man > foo.1Makefile 中的工具书写能够在 sh,而不是在 csh,中运行的 Makefile 命令(以及任何 shell,例如 c
14、onfigure)。不要使用任何 ksh 或者 bash 特殊的功能。为创建和安装而提供的 configure任何工具,除了以下的几个之外:和 Makefile 规则不要直接使用cat cmp cp echo egrep expr grepln mkdir mv pwd rm rmdir sed test touch坚持使用这些程序通常支持的选项。例如,因为许多系统不支持mkdir-p',尽管它可能有些方便, 但不要使用它。为创建和安装而提供的 Makefile 规则还可以使用编译器和相关的程序, 但应该通过 make 变量以便 用户对它们进行替换。下面是一些我们所说的相关的程序:ar
15、 bison cc flex install ld lexmake makeinfo ranlib texi2dvi yacc在你使用 ranlib 的时候,你应该测试它是否存在,并且仅仅在它存在的情况下运行它,以使得发布 版本在那些没有 ranlib 的系统中也能够工作。如果你使用了符号连接,你应该为没有符号连接的系统实现一个替代手段。你可以在只打算用于特的 Makefile 的部分(或者)中使用你能够确认在那些系统上存在的工具。为用户提供的标准目标所有的 GNU 程序应该在它们的 Makefile 中含有下列目标:all'编译整个程序。它应该是缺省目标。这个目标不需要重新创建任何文
16、档文件;Info 文件被包含在发布版本中, 同时,只有在用户明确地要求创建DVI 文件的时候才创建 DVI 文件。install'编译程序并且把可执行文件、库文件等文件到它们在实际应用中应该存在的位置。如果存在一个可以 检测程序是否被正确地安装了的简单测试,本目标将首先运行这个测试。如果文件的安装目录不存在,该命令将创建这样的目录。它们包括由变量 prefix 和 exec_prefix 的值指明的目录,以及需要的所有目录。完成该任务的式是按照后面所说明的 方式通过目标 installdirs 来完成。在任何用户安装 man 手册令之前使用-',以使得 make 忽略所有的错误
17、。 错误将在那些没有安装 Unix man 手册文档系统的系统中出现。安装 Info 文件的方式是用$(INSTALL_DATA)把它们到$(infodir)'中。 (参见为指明命令而提供的变量),并且如果有程序 install-info 存在, 那么就运行它。install-info 是一个把给定的 Info 文件添加 或者更新目录项的,它编辑 Info dir'文件以;它将是 Texinfo 包的一个部分。下面是用于安装一个 Info 文件一个简单规则:$(infodir)/: #There may be a newer info file
18、in . than in srcdir.-if test -f ; then d=.; else d=$(srcdir); fi; $(INSTALL_DATA) $d/ $; #Run install-info only if it exists.#Use if' instead of just prepending -' to the#line so we notice real errors from install-info.#We use $(SHELL) -c'because some shells do not#fail g
19、racefully whenthere is an unknown command.if $(SHELL) -c'install-info -version' >/dev/null 2>&1; then install-info -infodir=$(infodir) $d/;else true; fiuninstall'删除install'目标创建的所有安装的文件(但不包括那些由诸如make all' 之类的目标创建的,没有被安装的文件)。clean'从当前目录中删除所有在创建程序过程中创建的文件。不要删除那
20、些纪录配置情况的文件。有些文件可能是在创建 过程中创建的,但因为它们是和发布版本一起发布的,通常不是在创建过程中创建的,这样的文件也需要保留下来。如果.dvi'文件不是发布版本的一部分,就删除它们。distclean'从当前目录中删除所有在程序的配置和创建过程中创建的文件。如果你解包源代码并且在没有添加任何其它文件的 情况下创建程序, makedistclean'将仅仅保留那些出现在发布版本中的文件。mostlyclean'类似于clean',可能删除少数人们通常不希望重新编译的文件。例如,GCC 的 mostlyclean'目标删除libgcc
21、.a',这是因为很少需要重新编译并且重新编译将花费大量的时间。realclean'从当前目录中删除所有可以由 Makefile 重新创建的文件。这通常包括distclean 删除的文件, 以及:由 Bison 生成的 C 源文件、标记表(tags tables)、Info 文件等等。然而有一个例外:即使configure'可以通过使用 Makefile 中的规则重新创建,make realclean' 也删除configure'。更一般地说,makerealclean'将删除为了运行configure' 而存在的任何东西,并且随后开始创建
22、程序。TAGS'程序更新标记表(tags table)。info'生成所有需要的 Info 文件。书写该规则的最佳方式是:info: : foo.texi chap1.texi chap2.texi$(MAKEINFO) $(srcdir)/foo.texi你必须在 Makefile 中定义变量 MAKEINFO。它应该运行程序 makeinfo,该程序是 Texinfo 发布 版本的一部分。dvi'Generate DVI files for all TeXinfo documentation. For example:dvi: foo
23、.dvifoo.dvi: foo.texi chap1.texi chap2.texi$(TEXI2DVI) $(srcdir)/foo.texi你必须在 Makefile 中定义变量 TEXI2DVI。它应该运行程序 texi2dvi,该程序也是 Texinfo 发布版本的一部分。作为另一个选择,只要写依赖文件并且GNU Make 提供这个命令就行了。dist'建一个发布版本tar 文件。该tar 文件将被设置以使得在tar文件中的文件名以子目录名开头,这个子目录名 是包用于发布的名字。这个名字可以包含版本号。例如,GCC 版本 1.40 的发布 tar 文件将被解包到名为gcc-1
24、.40'的子目录中。完成该任务的最简单方式是以适当的名称创建一个子目录,使用 ln 或者 cp 把正确的文件 安装到该目录中,而后 tar 这个子目录。目标 dist 应该显式地依赖于发布版本中所有的非源文件,以确保它们在发布版本中都不是过时的。参见 制作发布包check'(如果有的话)执行自检测。用户必须在运前创建程序;你应该写下自检测以便 它们在安装之前进行工作。试之前,但不必在安装建之后而没有被对于那些适用于以下的目标的程序,建议你按照常用的名字提供它们。installcheck(如果有的话)执行安装监测。用户必须在运行该检测之前创建并且安装程序。你不应该假定$(bind
25、ir)' 出现在搜索路径中。installdirs添加一个名为installdirs'的目标,以便创建安装文件的目录和它们的父目录。 有一个称为mkinstalldirs'的可以为此提供便利;在Texinfo可以找到它。你可以使用象下面那样的规则:# Make sure all installation directories (e.g. $(bindir)# actually exist by making them if necessary.installdirs: mkinstalldirs$(srcdir)/mkinstalldirs $(bindir) $(d
26、atadir) $(libdir) $(infodir) $(mandir)为指明命令而提供的变量Makefile 应该提供变量以覆盖某些命令、选项等等。特别地,你应该通过变量来运行大部分工具程序。因此,如果你使用了Bison,就定义一个缺省值是通过BISON = bison' 来设定的变量 BISON,并且在你需要使用 Bison 的所有地方通过$(BISON)它。在这种方式下,文件管理工具:ln、rm、mv 等等并不需要通过变量,这是因为 用户不需要用其它替代它们。每个FLAGS'附加到变量都应该有一个对应的变量以便为程序提供选项。把变量名的后面就是 选项变量名-例如,BI
27、SONFLAGS。(名字 CFLAGS 是这项规则的一个例外,但因为它是标准的而保留了它。) 在任何运行预处理器的编译命令中使用 CPPFLAGS,在任何进行连接的编译命令和任何对 ld 的直接使用中 使用 LDFLAGS。如果存在一些为了正确地编译某些文件而必须使用的 C 编译器选项,不要把它们包括在 CFLAGS 中。用户希望 能够自由地指明 CFLAGS 的值。替代的方式是:通过在编译命令行中显式地给出这些必要的选项或者通过定义一条隐含 规则,从而以于 CFLAGS 的方式把选项传递给 C 编译器。CFLAGS = -gALL_CFLAGS = -I.$(CFLAGS).c.o:$(CC
28、) -c$(CPPFLAGS) $(ALL_CFLAGS) $<把选项-g'包括在CFLAGS 中,因为它对于正确的编译来说并不是必要的。 你可以认为它仅仅是关于缺省值的一个建议。如果包被设置成在缺省的状态下由 GCC 编译,那么你可能还需要把-O' 包括在 CFLAGS 的缺省值之中。把 CFLAGS 放在编译命令行的最后,就是在其它包含了编译选项的变量之后,以便于用户使用 CFLAGS 来覆盖其它的选项。每个 Makefile 都应该定义变量 INSTALL,它是把一个文件安装到系统中的基本命令。每个 Makefile 还应该定义变量 INSTALL_PROGRAM
29、和 INSTALL_DATA。(两者的缺省值都应该是 $(INSTALL)。)而后,Makefile 应该使用这些变量作为实际安装令,分别用于安装可执行文件和不可执行的文件。 按照下面的方式使用这些变量:$(INSTALL_PROGRAM) foo $(bindir)/foo$(INSTALL_DATA) libfoo.a $(libdir)/libfoo.a总是把文件名,而不是目录名,作为安装命令的第二个参数。为每个需要安装的文件使用令。为安装目录而提供的变量安装目录总是应该通过变量来命名,以易于把包安装在其它非标准的位置。这些变量的标准名字是:prefix'用于构造下列变量的缺省值
30、的前缀。 prefix 的缺省值应该是/usr/local'(至少现在是它)。exec_prefix'用于构造下列某些变量的缺省值的前缀。exec_prefix 的缺省值应该是$(prefix)。一般来说,$(exec_prefix)指的是用于储存与有关的文件(比如说可执行文件和子程序库)的目录, 而$(prefix)则被直接用于其它目录。bindir'用于储存用户可以运行的可执行程序的目录。一般来说应该是/usr/local/bin',但应该被写作 $(exec_prefix)/bin'。libdir'用于安装由程序运行,而不是由用户运行的可执
31、行文件的目录。Object文件和 object 代码库也应该被储存在这个目录。 提供该目录的意图是为了储存适用于特殊结构,但又不必出现在命令路径中的文件。libdir 的值通常是 /usr/local/lib',但应该被写作$(exec_prefix)/lib'。datadir'用于安装程序在运行时需要的只读数据文件的目录。该目录用于储存与使用的$(prefix)/lib'。的文件。它通常是 /usr/local/lib',但应该被写作statedir'用于安装程序在运行时需要修改的数据文件的目录。这些文件应该与使用的类型,并且应该可以在网络 安
32、装的情况不同的之间共享。它通常应该是/usr/local/lib',但应该被写作$(prefix)/lib'。includedir'用于储存将被用户程序以 C 预处理指令#include'引入的件的目录 。 它 通 常 应 该 是$(prefix)/include'。/usr/local/include' , 但 应 该 被 写 作除了 GCC 以外,大部分编译器并不在/usr/local/include'中寻找件。所以以这种方式安装件仅仅 适用于 GCC。但有些库被设计成与其它编译器共同工作。它们应该在两个地方安装它们的included
33、ir 给出,另一个由 oldincludedir 给出。件, 一个由oldincludedir'为除了 GCC 之外的其它编译器安装/usr/include'。件的目录。这通常应该是Makefile 命令应该检测 oldincludedir 的值是否为空。如果为空,Makefile 命令就不应该试图使用对件的第二个安装。oldincludedir;Makefile 命令应该放弃除非件来自一个不应该替换已经存在的件。因此,如果你的 Foo 包提供了一个件foo.h' , 并且如果它没有出现在oldincludedir 目录中或者 oldincludedir 目录中的foo
34、.h'也是来自 与Foo 包,那么 Foo 包就应该把件安装到 oldincludedir 中。为了判定foo.h'是否来自于 Foo 包,可把一个特殊的字作为注释的一部分放在文件中,而后用 grep 搜索这个 字。mandir'(如果存在)本包安装 man 手册的目录。它应该包含对应于正确的手册部 分 的 后 缀 - 对 于 一 个 工 具 来 说 通 常 是 1' 。 它 一 般 是/usr/local/man/man1',但你 应该把它写成:$(prefix)/man/man1'。man1dir'安装 man 手册第一部分的目录。m
35、an2dir'安装 man 手册第二部分的目录。.'如果包需要把 man 手册安装到手册系统的多个部分,就用这些名字来代替mandir'。不要把 man 手册作为 GNU 软件的主要文档。用 Texinfo 书写文档来代替它。Man 手册只是因为 人们在 Unix,它只是一个次要的应用程序,上运行GNU 软件才存在的。manext'作为需要安装的 man 手册的文件的扩展名。它应该是一个点加上一个适当的数字;通常它应该是:.1'。man1ext'将被安装到 man 手册第一部分的文件的扩展名。man2ext'将被安装到 man 手册第二部
36、分的文件的扩展名。.'如果包需要把 man 手册安装到手册系统的多个部分,就用这些名字代替manext'。infodir'包 安 装 Info 文 件 的 目 录 。 在 缺 省 状 态 下 , 它 应 该 是/usr/local/info',当它应该被写成 $(prefix)/info'。srcdir'用于编译源代码的目录。该变量的值通常是由 configureshell入的。插例如:# Common prefix for installation directories.# NOTE: This directory must exist wh
37、en you start the install.prefix = /usr/localexec_prefix = $(prefix)# Where to put the executable for the command gcc'.bindir = $(exec_prefix)/bin# Where to put the directories used by the compiler.libdir = $(exec_prefix)/lib# Where to put the Info dir = $(prefix)/info如果你的程序在一个标准的用户给定的目
38、录中安装了大量的文件,可能把为程序特别提供的文件存放到 子目录中会有用一些。如果你这样做了,你应该改写 install 规则以创建这些子目录。不要指望用户会把子目录名包括在上面列出的变量的值中。为安装目录提供统一的变量名集合的意图是 使得用户可以为一些不同的 GNU 包指明完全相同的值。为了使这些规定变得有用,所有的用户这样做的时候它们将能够有效地工作。必须这样设计 以便在配置是如何进行的每个 GNU 发布版本都应该还有一个名为 configure 的 shell。你需要希望在那种和系统上编译程序作为参数告诉这个。configure 必须配置信息以便它们可以影响编译工作。这样做的式是把一个诸如
39、config.h'的标准名字和为选定的系统匹配的 正确配置文件连接起来。如果你使用了这种技术,发布版本中就不应该包含名为 config.h'的文件。这样做是为了保证用户在配置前不能够创建它。configure 可以做的另一件事情是编辑 Makefile。如果你这样做了,发布 版本中就不能包含名为Makefile'的文件。用Makefile.in'来代替 它,并且Makefile.in'为 configure 的编辑提供了输入。同样, 这样做是为了保证用户在配置前不能创建它。如果 configure 生成了Makefile',那么Makefile&
40、#39; 就应该包含一个名为Makefile'的目标,这个目标将重新运行 configure 以与获取上一次配置相同的配置信息。由 configureMakefile'中被列出。的文件,应该作为 依赖性文件而在configure生成的文件在它们的第一行都应该包含一条注释以说明它们是由 configure 自动生成的。这样做是为了确保用户工 修改它们。试图手configure 应该写入一个名为config.status'的文件,该文件 说明了在程序的最后一次配置中给出了那些配置选项。该文件应该是一个shell,如果运行它, 将重新生成相同的配置。configure 应该接
41、受形式为-srcdir=dirname' 的选项以指明在那个目录中可以找到源代码(如果源代码不在当前目录中)。这使得可以在实际代码目录没有被修改的情况下,在分离的中创建程序成为可能。如果用户没有给出-srcdir',那么 configure 将在.' 和.'中寻找源文件。如果它在上述地方之一发现源文件,它就应该在那里使用它们。 否则,它应该报告它没有找到源文件,并且以非零状态。通常,支持-srcdir'的简单方式是通过编辑被放到 Makefile 中的一个 VPATH 的定义。可能有一些规则需要被显式地以指明源代码目录。为了达到这个 目的, config
42、ure 可以把一个名为 srcdir 的变量添加到Makefile 中, 该变量的值就是给定的目录。configure 还应该提供一个可以指明程序是究竟为那的选项。 这个选项看起来应该象:而创建any-system例如,一个 Sun 3 可能是m68k-sun-sunos4.1'。configure 需要能够解释所有对的似是而非的描述方式。因此,sun3-sunos4.1'应该是有效的别名。sun3-bsd4.2'也是如此, 因为 SunOS是基于 BSD 的并且没有其它的 BSD 系统被用于 Sun。对于许多说, 因为 Ultrix 和 BSD 之间的区别很少被注意到
43、,所以vax-dec-ultrix'将是vax-dec-bsd'的一个别名。但少数程序可能需要区分它们。这里有一个被称为config.sub'的 shell,你可以把它作为一个子程序使用 以检查系统类型并且对别名进行规范化。出现其它选项以指明关于的软件或者硬件的细节:-with-package'包 package 将被安装,所以把本包配置成与 package 一同工作。package 可能的取值包括x'、gnu-as'(或者 gas')、gnu-ld'、gnu-libc'和gdb'。-nfp'目标没有浮点数
44、处理器。-gas'目标的汇编器是 GAS,GNU 的汇编器。该选项已经过时了;用-with-gnu-as'来代替。-x'目标已经安装了 X Window 系统。该选项已经过时了;用-with-x'instead 来代替。所有的 configure都应该接受所有这些“细节”选项,而不论它们是否会对手头的特定 包产生影响。特别地,它们应该接受任何以-with-' 开头的选项。这样做是因为这使得用户 可以用同一组选项配置整个 GNU 源代码树。作为编译的一部分的包可能支持交叉编译(pliation)。在这种情况下,程序的主机和目标的系统类型当作主机和目标上运行
45、的程序。可能是不同的。configure 通常把指明,因此将创建与运行它 的类型相同的创建交叉编译器(piler)、交叉汇编器(cross-assembler)、或者你的程序,通过在运行 configure 时给出选项-host=hosttype'来完成。它在不影响 目标的情况下指明了主机名。hosttype 的语法与前面所说的一样。因为为互操作(cross-operation)配置整个操作系统是一件没有意义的事,对互操作来说没有意义的程序 就不必接受选项-host'。有些程序自动地配置它们。如果你的程序被设置成这样,你的configure只需要简单地 忽略它的大部分参数就行了
46、。使用 C 以外的语言使用 C 以外的语言就好像使用非标准特征:它将为用户带来麻烦。即使GCC 能够支持其它语言, 用户也可能因为不得不安装其它语言的编译器以创建你的感到不便。所以请使用 C 语言。这条规则有三个例外:如果有些程序包括了特殊语言的解释器,那么就可以使用这种语言。因此,GNU Emacs 包含用Emacs Lisp 写的代码就没有问题,因为GNU Emacs包含了 Lisp 解释器。如果一个工具就是为了某种语言而编写的,那么就可以使用那种语言。这是因为那些需要创建这个工具的人必然是那些已经安装了其它语言的人。如果一个应用程序没有被面就不是特别重要。广泛地关注,那么应用程序的安装不
47、太方格式化你的源代码把作为 C 函数的开头的括号放到第零列是十分重要的,并且避免把或者左方括号放到第零列。有些工具通过寻C 函数的起点。这些工具将不能 处理那些不任何其它的找在第零列的括号、左括号括号来寻找按照这种方式排版的代码。对于函数定义来说,把函数名的起始字符放到第零列也同样重要。这帮助任何寻找函数定义,并且确的格式应该是:可能有助于帮助某些工具识别它们。因此,正static char *concat (s1, s2)/* Name starts in column zero here */char *s1, *s2;/* Open brace in column zero here *
48、/.或者,如果你希望使用标准 C,定义的格式是:static char *concat (char *s1, char *s2).在标准 C 中,如果参数不能够被美观地放在一行中,按照下面的方式把它们:intlots_of_args (int an_integer, long a_long, short a_short,double a_double, float a_float).对于函数体,我们希望它按照如下方式排版:if (x < foo (y, z)haha = bar4 + 5;elsewhile (z)haha += foo (z, z);z-;return +x + bar
49、 ();我们发现如果在左括号之前以及逗号之后添加空格将使程序更加容易阅读。尤其是在 逗号之后添加空格。当我们把一个表达式分成多行的时候,在操作符之前而不是之后分割。下面是正确的方式:if (foo_this_is_long && bar > win (x, y, z)&& remaining_condition)尽力避免让两个不同优先级的操作符出现在相同的对齐不要象下面那样写:。例如,mode = (inmodej = VOIDmode|GET_MODE_SIZE(outmodej)>GET_MODE_SIZE(inmodej)? outmodej
50、: inmodej);应该附加额外的括号以使得文本缩进可以表示出这种嵌套:mode = (inmodej = VOIDmode|(inmodej)(GET_MODE_SIZE(outmodej)>GET_MODE_SIZE? outmodej : inmodej);额外的括号以使得 Emacs 可以正确地对齐它们。例如,如果你手工完成缩进工作, 那么它们看起来不错,但 Emacs 将把它们混在一起:v = rup->ru_utime.tv_sec*1000 + rup->ru_utime.tv_usec/1000+ rup->ru_stime.tv_sec*1000 +
51、 rup->ru_stime.tv_usec/1000;但添加一组括号解决了这个问题:v = (rup->ru_utime.tv_sec*1000 + rup->ru_utime.tv_usec/1000+ rup->ru_stime.tv_sec*1000 + rup->ru_stime.tv_usec/1000);按照如下方式排版 do-while 语句:doa = foo (a);while (a > 0);请按照逻辑关系(而不是在函数中)使用走纸字符(control-L)以把程序划分成页。 页有多长并不重要,因为它们不必被放在一个打印的页中。走纸字符
52、应该单独地出现在一行中。为你的工作写注释每个程序都应该以一段简短地、说明其功能的注释开头。 例如:fmt -filter for simple filling of text'.请为每个函数书写注释以说明函数做了些什么,需要哪些种类的参数,参数可能值的含义 以及用途。如果按照常见的方式使用 C 语言类型,就没有必要逐字重写 C 参数的含义。如果 它使用了任何非标准的东西(例如,一个类型为 char *的参数实际上给出了 一个字的第二个字符,而不是第一个字符,的地址),或者是可能导致函数不能工作的 任何可能的值(例如,不能保证正确处理一个包含了新行的字),请确认对它们进行了说明。如果存在
53、重要的返回值,也需要对其进行解释。请在你的注释之后添加两个空格,以便 Emacs 句子命名进行处理。还有,请书写完整的句子 并且使头一个单词以大写字母开头。如果小写字母组成的标识符出现在句子的开头,不要把它 变成大写的!修改拼写就了不同的标识符。如果你不希望句子以小写字母开头,可以写下 不同的句子(例如,“The identifier lower-case is .”)。如果你使用参数名来说明参数值,关于函数的注释就会更清晰。变量名本身应该是小写的, 但在你说到它的值而不是变量本身的时候就使用大写字母。因此,“the inode number node_num” 比“an inode”要好。通
54、常在函数之前的注释中没有必要重新提到函数的名字,因为读者可以看到它。 一种可能的例外是:注释太长了,以至于函数本身被挤出了屏幕底端之外。对于每个静态变量,也象下面那样应该提供注释:/* Nonzero means truncate lines in the display;zero means continue them.*/int truncate_lines;除非#endif'是一个没有嵌套而且很短(只有几行)的条件,每个#endif'都应该含有一个注释。注释应该说明它所结束的条件,包括它的含 义。 #else'应该含有一个说明条件与随后代码的含义的注释。例如:#i
55、fdef foo.#else /* not foo */.#endif /* not foo */但相反,按照如下方式为#ifndef'写注释:#ifndef foo.#else /* foo */.#endif /* foo */清晰地使用 C 语言成分请显式地函数的所有参数。不要因为它们是整数就忽略它们。对外部函数以即将随后出现在源文件中的函数的应该出现在靠近文件开头 (在第一个函数定义之前的某个地方)的同一个地方。或者其它的应该出现在件中。 不要在函数中放置外部。在过去一种常见的做法是在同一个函数中把同一个局部变量(比如说名为 tem 的变量 反复地用于不同的值。但现在,更好的方式是为每个不同的目的分别定义局部变量,并且给它们以更 有意义的名字。这不仅仅是程序更容易理解,它还会被好的编译程序所优化。你还可以把对局部变量 的声明放到包含对它的使用的最小范围中。这可以把程序变得更清晰。不要使用可以遮蔽全局标识符的局部变量和参数。不要在了行的中多个变量。在每一行中都以一个新的开头。例如,不应该:intfoo,bar;而应该:int foo, bar;或者:int foo;int bar;(如果它们是全局变量,在它们之中的每一个之前都应该添加一条注释。)当你在一个 if 语句中嵌套了另一个 if-else
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 英语学习之旅的试题及答案
- 普法考试试题及答案多选
- 江苏英文面试题及答案
- 施工安全检查与评估试题及答案
- 英语二中考试卷及答案
- 数字与图形相关问题的分析题试题及答案
- 挑战2025年注册土木工程师试题及答案
- 秘书学1试题及答案
- 施工现场安全管理的未来发展方向试题及答案
- 电磁波性质探讨试题及答案
- 2025年4月新高考语文全国Ⅰ卷各地模考试题汇编之语用
- 山东省聊城市2025年高考模拟试题(二)数学+答案
- 小学数学西师大版(2024)三年级下册旋转与平移现象教学设计
- (一模)惠州市2025届高三4月模拟考试英语试卷(含答案)
- 田园综合体可行性研究报告
- 2025年中考语文二轮复习:散文阅读 专题练习题(含答案)
- 2025届新高考教学教研联盟高三第二次联考政治试题及答案
- 赌博酒驾警示教育
- 产业园物业管理实施方案
- 管理学基础-形考任务三-国开-参考资料
- 梁晓声母亲测试题及答案
评论
0/150
提交评论