C/C++编程安全标准GJB-8114解读——名称、符号与变量使用类

GJB-8114标准是一部嵌入式软件安全测试相关的国家标准,它包括声明定义、版面书写、指针使用、分支控制、跳转控制、运算处理、函数调用、语句使用、循环控制、类型转换、初始化、比较判断、名称、符号与变量使用等多个方面的规定和要求。这些规则是为了保证软件在整个发展过程中的安全性,经过总结归纳而来的强制性规则,旨在提高代码的质量和可靠性,减少潜在的错误和风险。通过GJB-8114标准,可以帮助我们学习嵌入式软件的测试方法,实验室申请CNAS相关领域的相关资质时也会用到该标准。今天我们继续为大家介绍GJB-8114系列内容中的名称、符号与变量使用类规则。

名称、符号与变量使用类

这类一共有16条,实际上是涉及到一些命名规则的标准。

R-1-13-1

禁止局部变量与全局变量同名

比如说违背示例中,有一个全局变量,那么我们的局部变量就不允许再使用这个。这个局部变量还包括什么呢?大家一定要记住还包括里面的参数,也就是说这个参数也不允许与全局变量同名。

R-1-13-2

禁止函数形参与全局变量同名

这个违背示例中展示的很清楚了,就不解释了。

R-1-13-3

禁止函数与全局变量同名

现在好像很少这样做了,原来很多人做加解密的时候,定义一个变量,给它分配一个空间,自己装入二进制码,然后直接把程序都控制成相应的变量,这个变量就跟子程序就一样了,这个时候你就分不清到底是子程序还是变量,所以会要求不能同名。

R-1-13-4

禁止变量与标识同名

我们定义了很多的类型、结构,给它取了一些的标识,然后定义的变量跟这个标识重名了,是不允许这样的。尽管有时候不会出问题,但是也是不允许的。

R-1-13-5

禁止变量与枚举同名

这个变量跟枚举里的某一个元素同名也是不允许的。

R-1-13-6

禁止用自定义关键字做为变量名

像违背示例中展示的,你定义了一种关键字,把某一种类型定义成了自己比较熟悉的名字,然后又把它做成了变量名,这是不允许的。

R-1-13-7

禁止在模块内部重定义变量

这个在C++中这样写有可能不会出问题,编译也不会出问题。但是C++中有一个作用域的概念,不同的乘积里面,可以多次定义这个变量。现在有的编译器已经对这种情况进行了限制,要求不能重复定义。

还有一个问题,在这里要引申一下。通常咱们学C++的人,书上会告诉你,用一个变量的时候,尽量离我们用的最近的地方定义这个变量,但是现在咱们的规则里规定,所有的变量都在函数头上定义,都在前面定义,后面可以用。你有可能在一个函数前面定义一个变量,在一个两三百行的函数中最后几行才用到这个变量,这也是有可能的。

R-1-13-8

禁止仅依赖大小写区分的变量

比如说违背示例中展示的,就是大小写不一样,实际上C语言是可以区分这种不同的变量的,但是汇编不能区分它们的不同,认为它俩是一个。

R-1-13-9

禁止仅依赖小写字母"l"与数字"1"区分的变量

这个是说,有可能你是看不出来你定义的是1还是l,像违背示例中定义了一个a1,定义了一个al,这样你在后面用的时候,就有可能把它用混了。

R-1-13-10

禁止仅依赖大写字母"O"与数字"0"区分的变量

像违背示例中展示的,在咱们的计算机中,这样写你可能有时候根本就分不清楚它到底是0还是O。

R-1-13-11

禁止单独使用小写字母"l"或大写字母"O"作为变量名

为什么单独提出这两个字母呢,最主要的原因是一个太像1了,一个太像0了。

R-1-13-12

程序外部可改写的变量,必须使用volatile类型说明

这个通常的情况是,有一个变量,它就是一个硬件的地址,里是由硬件来驱动的,一直在修改它,这时候,你定义这个地址作为一个变量的时候,应该用volatile类型。这样才能确保在你用到这个变量的时候,它都会从内存中取数。

否则它有可能是将这个变量的值,放在一个寄存器里面,用的时候是从寄存器里取,这个时候虽然你的内存已经变了,但是寄存器里面的并没有变。所以用volatile类型强制地告诉计算机,我用它的时候一定从内存中取。

R-1-13-13

禁止在表达式中出现多个同一volatile类型变量的运算

像违背示例中展示的,flag是一个volatile类型,也就是说它是一个随时变化的量,对它进行运算,再赋给它,这样就会导致内存里的数和缓存里的不一样,因为如果不是这种随时更新的类型,对它进行计算都是放到寄存器中进行计算。这里我们把它从内存中取到寄存器中进行计算时,它有可能变了,就会造成一个很混乱的现象,所以不允许这样做。

R-1-13-14

禁止将NULL作为整型数0使用

NULL通常是我们在头文件中定义的空,往往把它定义成一个0,或者0l等等,不能把它作为整型数使用。这个往往不是我们自己定义的,C语言很多头文件里都对它进行了定义,所以咱们直接引用它并没有什么错误,但是不要把它当作一个数,它往往是一个指针类型。最主要的原因是因为它是一个指针类型,对于指针可以直接赋值,但是对于它就不可以了。

R-1-13-15

禁止给无符号类型变量赋负值

像违背示例中展示的,b是一个整型,可以把它赋成-1。a是无符号的,应该是大于等于0的的数,一旦把这个-1赋给它,就会变成65535,变成了4个f,如果要是32位的,就会变成8个f,就变成了最大数。

R-1-13-16

用于表示字符串的数组必须以'\0'结束

这个是说,你要是对一个char型的数组赋值的话,按照示例中那样赋,最后都得赋全了。像char c[5]="abcd"这样,它本身是一个字符串,这个字符串的意思就是以\0结尾,所以这样赋值是允许的。

整个的强制性规则大致上就是这些,大家在使用的时候要根据实际的情况进行一些取舍,有些强制性的规则会实实在在造成程序运行出问题的,有些可能不会出问题。对于一些非强制性的一些企业,比如说非军工、非宇航的行业,这些强制性的规则可能就不是完全适用,但是如果设计到一些军工、宇航等,这些强制性规则还是要遵守的,如需嵌入式软件代码测试作业指导书可私信我交流。

本系列内容整理自优品软件培育计划百场前沿技术系列讲座直播第16期,中国航天科技集团公司软件评测中心研究员李国良为大家带来的《白盒测试------C/C++编程规范》专题讲座,他曾参与过多个大型航空、航天、军工、电子型号项目的测试任务,如需直播回放视频也可私信我获取。

(谢绝转载,更多内容可查看我的专栏)

相关推荐
ChoSeitaku7 分钟前
12.重复内容去重|添加日志|部署服务到Linux上(C++)
linux·c++·windows
挣扎与觉醒中的技术人12 分钟前
网络安全入门持续学习与进阶路径(一)
网络·c++·学习·程序人生·安全·web安全
martian66514 分钟前
【Java高级篇】——第16篇:高性能Java应用优化与调优
java·开发语言·jvm
m0_7482500316 分钟前
springboot使用logback自定义日志
java·spring boot·logback
-优势在我19 分钟前
Android TabLayout 实现随意控制item之间的间距
android·java·ui
Lojarro34 分钟前
JavaEE基础之- Servlet相关
java·servlet·java-ee
KingDol_MIni1 小时前
Spring Boot 集成 T-io 实现客户端服务器通信
java·服务器·spring boot
OTWOL1 小时前
【C++编程入门基础(一)】
c++·算法
许苑向上1 小时前
Java八股文(下)
java·开发语言
谏君之1 小时前
C语言实现的常见算法示例
c语言·算法·排序算法