软 件 编 程 规 范
    环境
二    语言扩展
三    文档
四    字符集
五    标识符
六    类型
七    常量
八    声明与定义
九    初始化
十    数值类型转换
十一  指针类型转换
十二  表达式
十三  控制语句表达式
十四  控制流
十五  switch语句
十六  函数
十七  指针和数组
十八  结构与联合
十九  预处理指令
二十  标准库
二十一 运行时错误
一 环境
规则1.1(强制): 所有代码都必须遵照ISO 9899:1990 Programming languages - C”,由ISO/IEC 9899/COR1:1995ISO/IEC 9899/AMD1:1995,和ISO/IEC9899/COR2:1996 修订。
规则1.2(强制): 不能有对未定义行为或未指定行为的依赖性。
这项规则要求任何对未定义行为或未指定行为的依赖,除非在其他规则中做了特殊说明,都应该避免。如果其他某项规则中声明了某个特殊行为,那么就只有这项特定规则在其需要时给出背离性。
规则1.3(强制): 多个编译器和/或语言只能在为语言/编译器/汇编器所适合的目标代码定义了通用接口标准时使用。
如果一个模块是以非C 语言实现的或是以不同的C 编译器编译的,那么必须要保证该模块能够正确地同其他模块集成。C 语言行为的某些特征依赖于编译器,于是这些行为必须能够为使用的编译器所理解。例如:栈的使用、参数的传递和数据值的存储方式(长度、排列、别
名、覆盖,等等)。
规则1.4(强制): 编译器/链接器要确保31 个有效字符和大小写敏感能被外部标识符支持。
ISO 标准要求外部标识符的头6 个字符是截然不同的。然而由于大多数编译器/链接器允许至少31 个有效字符(如同内部标识符),因此对这样严格而并不具有帮助性的限制的适应性被认为是不必要的
必须检查编译器/链接器具有这种特性,如果编译器/链接器不能满足这种限制,就使用编译器本身的约束。
规则1.5(建议): 浮点应用应该适应于已定义的浮点标准
浮点运算会带来许多问题,一些问题(而不是全部)可以通过适应已定义的标准来克服。其中一个合适的标准是 ANSI/IEEE Std 754 [21]
同规则6.3 相一致,浮点类型的定义提供了一个注释所用浮点标准的机会,如:
/* IEEE 754 single-precision floating-point */
typedef float float32_t;
二 语言扩展
规则2.1(强制): 汇编语言应该被封装并隔离。
在需要使用汇编指令的地方,建议以如下方式封装并隔离这些指令:(a) 汇编函数、(b) C函数、(c) 宏。
出于效率的考虑,有时必须要嵌入一些简单的汇编指令,如开关中断。如果不管出于什么原因需要这样做,那么最好使用宏来完成。
需要注意的是,内嵌的汇编语言的使用是对标准C 的扩展,因此也需要提出对规则1.1的背离。
#define NOP asm (“ NOP”);
规则2.2(强制): 源代码应该使用 /*…*/ 类型的注释。
这排除了如 // 这样C99 类型的注释和C++类型的注释,因为它在C90 中是不允许的。许多编译器支持 // 类型的注释以做为对C90 的扩展。预处理指令(如#define)中 // 的使用可以改变,/*…*///的混合使用也是不一致的。这不仅是类型问题,因为不同的编译器(在C99之前)可能会有不同的行为。
规则2.3(强制): 字符序列 /* 不应出现在注释中。
C 不支持注释的嵌套,尽管一些编译器支持它以做为语言扩展。一段注释以/*开头,直到第一个*/为止,在这当中出现的任何/*都违反了本规则。考虑如下代码段:
/* some comment, end comment marker accidentally omitted
<<New Page>>
Perform_Critical_Safety_Function (X);
/* this comment is not compliant */
在检查包含函数调用的页中,假设它是可执行代码。因为可能会省略掉注释的结束标记,那
么对安全关键函数的调用将不会被执行。
规则2.4(建议): 代码段不应被“注释掉”(comment out)。
当源代码段不需要被编译时,应该使用条件编译来完成(如带有注释的#if union是什么类型#ifdef 结构)。为这种目的使用注释的开始和结束标记是危险的,因为C 不支持嵌套的注释,而且已经存在于代码段中的任何注释将影响执行的结果。
三 文档
规则3.1(强制): 所有实现定义(implementation-defined)的行为的使用都应该文档化。本规则要求,任何对实现定义的行为的依赖——这些行为在其他规则中没有特别说明的——都应该写成文档,例如对编译器文档的参考。如果一个特定的行为在其他规则中被显式说明了,那么只有那项规则在其需要时给出背离。完整问题的描述详见ISO 9899:1990 附录 G[2]
规则3.2(强制): 字符集和相应的编码应该文档化。
例如,ISO 10646 [22]定义了字符集映射到数字值的国际标准。出于可移植性的考虑,字符常量和字符串只能包含映射到已经文档化的子集中的字符。
规则3.3(建议): 应该确定、文档化和重视所选编译器中整数除法的实现。
当两个有符号整型数做除法时,ISO 兼容的编译器的运算可能会为正或为负。首先,它可能以负余数向上四舍五入(如,-5/3 = -1,余数为-2),或者可能以正余数向下四舍五入(如,-5/3 = -2,余数为+1)。重要的是要确定这两种运算中编译器实现的是哪一种,并以文档方式提供给编程人员,特别是第二种情况(通常这种情况比较少)。
规则3.4(强制): 所有#pragma 指令的使用应该文档化并给出良好解释。
这项规则为本文档的使用者提供了产生其应用中使用的任何pragma 的要求。每个pragma的含义要写成文档,文档中应当包含完全可理解的对pragma 行为及其在应用中之含义的充分描述。应当尽量减少任何pragma 的使用,尽可能地把它们本地化和封装成专门的函数。
规则3.5(强制): 如果做为其他特性的支撑,实现定义(implementation-defined)的行为和位域(bitfields)集合应当文档化。
这是在使用了规则6.4 和规则6.5 中描述的非良好定义的位域时遇到的特定问题。C 当中的位域是该语言中最缺乏良好定义的部分之一。位域的使用可能体现在两个主要方面:

发表评论