MISRA C2012学习笔记(10)-Rules 8.15

文章目录

    • 8.15 控制流(Control flow)
      • Rule 15.1 不应使用 goto 语句
      • Rule 15.2 goto 语句仅允许跳到在同一函数中声明的稍后位置的标签
      • Rule 15.3 goto 语句引用的标签必须在 goto 语句所在代码块或包含该代码块的上级代码块中声明
      • Rule 15.4 最多只能有一个用于终止循环语句的 break 或 goto 语句
      • Rule 15.5 应仅在函数的末尾有单个函数出口
      • Rule 15.6 循环语句和选择语句的主体应为复合语句
      • Rule 15.7 所有的 if…else if 构造都应以 else 语句结束

8.15 控制流(Control flow)

Rule 15.1 不应使用 goto 语句

等级:建议

分析:可判定,单一编译单元

适用:C90,C99

原理:不受约束地使用goto会导致程序的非结构化和极难理解

在某些情况下,全面禁止goto需要引入flag以确保正确的控制流,而但这些标志本身可能不如它们替换的goto 清晰。因此,如果不遵守此规则,则允许在遵守规则15.2和规则15.3的指导下限制使用goto

解读:该规则需要被实施,嵌入式代码中不应使用goto

Rule 15.2 goto 语句仅允许跳到在同一函数中声明的稍后位置的标签

等级:必要

分析:可判定,单一编译单元

适用:C90,C99

原理:不受约束地使用goto会导致程序的非结构化和极难理解

限制goto的使用以禁止“back”跳转,确保迭代只在使用语言提供的迭代语句时发生,从而帮助最小化可视化代码的复杂性

示例:

void f ( void )
{int32_t j = 0;
L1:++j;if ( 10 == j ){goto L2;         /* 合规 */}goto L1;           /* 违规 */
L2 :++j;
}

解读:如果要使用goto的话,只能往后面的标签跳,不能往前跳。

Rule 15.3 goto 语句引用的标签必须在 goto 语句所在代码块或包含该代码块的上级代码块中声明

等级:必要

分析:可判定,单一编译单元

适用:C90,C99

展开:为符合此规则的设计目的,将不包含复合语句(复合语句:{}括起来的语句)的 switch 子句也视为一个代码块(即不用{}括起来的 case 子句也被视为独立的代码块)

原理:不受约束地使用goto会导致程序的非结构化和极难理解
防止块之间或嵌套块之间的跳转有助于最小化可视化代码的复杂性

注意:当使用变量修改类型时,C99的限制更大。试图从具有可变修改类型的标识符的作用域外跳转到该作用域将导致违反约束。

示例:

void f1 ( int32_t a )
{if ( a <= 0 ){goto L2;            /* 违规 - L2 在其他代码块中 */}goto L1;              /* 合规 - L1 在同代码块 */if ( a == 0 ){goto L1;            /* 合规 - L1 在包含此goto语句的上级代码块中     */}goto L2;              /* 违规 - L2 在子代码块中 */
L1:if ( a > 0 ){L2:;}
}

在下面的示例中,标签 L1 在包含 goto 语句的块的块中定义。但是,发生了从一个swtich 子句到另一个 switch 子句的跳转,而由于此规则的目的,将 switch 的子句视为代码块,因此这个 goto 语句是违规的。

switch ( x )
{case 0:if ( x == y ){goto L1;}break;case 1:y = x;
L1:++x;break;default:break;
}

解读:该规则需要被实施,最好是不用goto

Rule 15.4 最多只能有一个用于终止循环语句的 break 或 goto 语句

等级:建议

分析:可判定,单一编译单元

适用:C90,C99

原理:限制循环的退出数量有助于最小化可视化代码的复杂性。当需要提前终止循环时,使用一个break或goto语句可以创建一个次要退出路径。

示例:下面嵌套的两个循环均合规,因为每个循环都只有一个 break 语句用于提前终止循环。

for ( x = 0; x < LIMIT; ++x )
{if ( ExitNow ( x ) ){break;}for ( y = 0; y < x; ++y ){if ( Exit Now ( LIMIT - y ) ){break;}}
}

下面循环违规,因为有多个 break 和 goto 语句用于提前终止循环。

for ( x = 0; x < LIMIT; ++x )
{if ( BreakNow ( x ) ){break;}else if ( GotoNow ( x ) ){goto EXIT;}else{KeepGoing ( x );}
}
EXIT:;

在下面示例中,内部 while 循环是合规的,因为它只有一个 goto 语句可能导致其提前终止。 但是, 外部 while 循环是违规的,因为它可以通过 break 语句或内部 while 循环中的 goto 语句提前终止。

while ( x != 0u )
{x = calc_new_x ( );if ( x == 1u ){break;}while ( y != 0u ){y = calc_new_y ( );if ( y == 1u ){goto L1;}}
}
L1:
z = x + y;

解读:一个循环中只能有一个break,保证代码可读性

Rule 15.5 应仅在函数的末尾有单个函数出口

等级:建议

分析:可判定,单一编译单元

适用:C90,C99

展开:一个函数最多只能有一个 return 语句。使用 return 语句时,它应该是复合语句构成的函数主体的最后一条语句。

原理:IEC 61508 和 ISO 26262 都要求函数有单出口,这是模块化方法要求的一部分。

提早返回可能会导致意外删除函数终止代码。

如果函数的出口点散布着会产生持久副作用的语句,则很难确定执行函数时将发生哪些副作用。

示例:在下面的违规代码示例中,提前返回被用于验证函数形参。

bool_t f ( uint16_t n, char *p )
{if ( n > MAX ){return false;}if ( p == NULL ){return false;}return true;
}

解读:该规则可以不被实施,实际会出现提前函数返回的情况

Rule 15.6 循环语句和选择语句的主体应为复合语句

等级:必要

分析:可判定,单一编译单元

适用:C90,C99

展开:循环语句(while,do…while 或 for)或选择语句(if,else,switch)的主体应为复合语句({}括起来的语句)

原理:开发人员可能会错误地认为,由于一系列语句的缩进,它们构成了迭代语句或选择语句的主体。控制表达式后面意外包含分号是一种特殊的危险,会导致控制语句为空。

使用复合语句清楚地定义了哪些语句实际上构成了主体。

此外,缩进可能会导致开发人员将else语句与错误的if语句关联起来

**例外 :**如果 if 语句紧随 else 出现,则这个 if 语句不必被包含在符合语句中(即允许 else if 语句出现)

示例:复合语句的布局及包围它的花括号位置是样式问题,本文档不解决。 以下示例中使用的样式不是强制性的。

while (data_available) 
process_data();  /* 违规,没有加括号*/ 
while (data_available) 
process_data(); /* 违规,没有加括号*/
service_watchdog(); 

其中service_watchdog()应该被添加到循环体中。复合语句的使用显著地减少了发生这种情况的机会

下面示例中,action_2()看上去是第一个 if 的 else 语句。

if ( flag_1 )if ( flag_2 )                 /* 违规,没有加括号 */action_1 ( );               /* 违规,没有加括号 */
elseaction_2 ( );                 /* 违规,没有加括号 */

而它的实际行为是:

if ( flag_1 )
{if ( flag_2 ){action_1 ( );}else{action_2 ( );}
}

复合语句的使用可确保明确定义 if 和 else 间的关联。

例外允许使用else if,如下所示

if ( flag_1 )
{action_1 ( );
}
else if ( flag_2 )              /* 合规 - 符合例外 */
{action_2 ( );
}
else
{;
}

以下示例显示了意外的分号如何导致错误:

while ( flag );                 /* 违规,分号导致可能出现死循环 */
{flag = fn ( );
}

以下示例显示了循环主体为空的合规方法:

while (!data_available) 
{ 
} 

解读:该规则需要被实施,一方面可以提高代码可读性,另一方面,可以检查出部分错误代码,例如while错误的分号

Rule 15.7 所有的 if…else if 构造都应以 else 语句结束

等级:必要

分析:可判定,单一编译单元

适用:C90,C99

展开:当 if 语句后接一个或多个 else if 构造的序列时,应始终以 else 语句作为结尾。 else 语句至少应包含一个副作用或注释。

原理:用 else 语句终止 if…else if 序列的序列是防御性编程,相似的,还有 switch 语句中对 default 子句的要求(请参见规则 16.5)。

else 语句必须具有副作用或注释,以确保对所需的行为给出肯定的指示,以帮助代码检查过程。

注意:简单的if语句不需要最后的else语句

示例:以下违规示例中,没有明确使用 else 语句结尾以指示不再执行任何操作

if ( flag_1 )
{action_1 ( );
}
else if ( flag_2 )
{action_2 ( );
}/* 违规,无else */ 

下面显示了一个符合标准的终止 else 示例。

else
{;   /* No action required - ; is optional */
}

解读:该规则目的主要是增加代码可读性,else里即使没有操作,也要进行注释来明确。实际实施的意义不大

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/63490.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[ACL 2024] ReFT: Reasoning with REinforced Fine-Tuning

Contents IntroductionMethodExperimentsReferences Introduction 作者提出 Reinforced Fine-Tuning (ReFT) 进行在线强化学习&#xff0c;帮助模型输出正确的推理步骤&#xff0c;总体感觉在线学习的思路和 STaR 非常相似&#xff0c;就是把 SFT 换成了 PPO… Method Warm-…

DDOS分布式拒绝服务攻击

DDOS分布式拒绝服务攻击 简单来说 传统的DOS就是一台或者多台服务对一个受害目标&#xff08;服务器&#xff0c;路由&#xff0c;ip&#xff0c;国家&#xff09;进行攻击&#xff0c;当范围过大时就是DDOS。目的就是通过大规模的网络流量使得正常流量不能访问受害目标&…

JavaSE——泛型编程

一、为什么要引入泛型编程 看这段代码&#xff1a; //传统方法&#xff1a; ArrayList list new ArrayList(); list.add(new Dog("小黄",5)); list.add(new Dog("小黑",1)); list.add(new Dog("小财",10)); //编译器发现不了这种问题&#xff…

深度优先的艺术:探索二叉树的深搜算法精髓

文章目录 前言☀️一、计算布尔二叉树的值&#x1f319;解法⭐代码 ☀️二、求根节点到叶节点数字之和&#x1f319;解法⭐代码 ☀️三、二叉树剪枝&#x1f319;解法⭐代码 ☀️四、验证二叉搜索树&#x1f319;解法☁️步骤⭐代码 ☀️五、二叉搜索树中第k小的元素&#x1f3…

VB.net进行CAD二次开发(二)与cad交互

开发过程遇到了一个问题&#xff1a;自制窗口与控件与CAD的交互。 启动类&#xff0c;调用非模式窗口 Imports Autodesk.AutoCAD.Runtime Public Class Class1 //CAD启动界面 <CommandMethod("US")> Public Sub UiStart() Dim myfrom As Form1 New…

linux ls -l 输出 drwxr-xr-x 2 root root 4096 Dec 5 21:48 rootTest 是什么意思

在Linux系统中&#xff0c;ls -l命令用于以长格式列出目录内容的详细信息。输出的一行通常包含以下部分&#xff1a; drwxr-xr-x 2 root root 4096 Dec 5 21:48 rootTest这一行的各个部分意义如下&#xff1a; drwxr-xr-x&#xff1a;这是文件类型和权限的标识。 第一个字符d…

python学opencv|读取图像(五)读取灰度图像像素

【1】引言 前序学习了图像的基本读取&#xff0c;掌握了imread()、imshow()和imwrite()函数的基本功能和使用技巧&#xff0c;参考文章链接为&#xff1a; python学opencv|读取图像-CSDN博客 然后陆续掌握了彩色图像保存、图像放大和缩小以及对imshow()函数的大胆尝试技巧&a…

基于yolov8的SAR影像目标检测系统,支持图像、视频和摄像实时检测【pytorch框架、python源码】

更多目标检测、图像分类识别、目标追踪等项目可看我主页其他文章 功能演示&#xff1a; 基于yolov8的SAR影像目标检测系统&#xff0c;支持图像、视频和摄像实时检测【pytorch框架、python源码】_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于yolov8的SAR影像目标…

2.Flink的项目初始化和Hello-world

目录 1.Flink项目初始化 2.Hello-world 1.Flink项目初始化 新建maven项目或者gradle项目&#xff0c;这里使用maven项目为例。 在项目的pom.xml文件中添加Flink依赖&#xff0c;如下所示&#xff0c;为Hello-World例子的最小依赖&#xff1a; <properties><maven.c…

ESP32开发 云调试

https://blog.csdn.net/weixin_43794311/article/details/128722001 VScode支持的仿真平台 https://docs.wokwi.com/zh-CN/vscode/getting-started 编译&#xff1a;Ctrl Alt B上传并重启模拟器&#xff1a;CtrlShifB Wokwi:Start Simulator调试&#xff1a;CtrlShifB Wokwi…

如何写出一篇好的论文?

写出一篇好的论文需要综合多方面的要素&#xff0c;从选题到最终成文&#xff0c;每一步都至关重要。首先&#xff0c;明确研究主题和目标&#xff0c;确保选题具有创新性、可行性和实际意义。接着&#xff0c;进行深入的文献检索和综述&#xff0c;了解当前领域的研究现状和前…

模版方法模式的理解和实践

在软件开发中&#xff0c;设计模式为我们提供了一套经过验证的解决方案&#xff0c;用于解决常见的设计问题。其中&#xff0c;模版方法模式&#xff08;Template Method Pattern&#xff09;是一种行为设计模式&#xff0c;它定义了一个算法的框架&#xff0c;并允许子类在不改…

洛谷【排序】算法的题单 - 笔记

2024-12-09 - 第 37 篇 洛谷【排序】题单 - 笔记 作者(Author): 郑龙浩 / 仟濹(CSND账号名) 洛谷【排序】题单合集 一、排序算法都有… 1. 简单排序算法 这些算法通常是基础的排序方法&#xff0c;容易理解和实现&#xff0c;但效率较低&#xff0c;适用于数据量较小的情况…

MySQL--》如何在SQL中巧妙运用函数与约束,优化数据处理与验证?

目录 函数使用 字符串函数 数值函数 日期函数 流程函数 约束 函数使用 函数是指一段可以直接被另一段程序调用的程序或代码&#xff0c;在mysql当中有许多常见的内置函数&#xff0c;接下来开始对这些内置函数及其作用进行简单的讲解和使用&#xff1a; 字符串函数 my…

归有光,情感与真实的独行者

归有光&#xff0c;字熙甫&#xff0c;号震川&#xff0c;生于明孝宗弘治十年&#xff08;公元1507年&#xff09;&#xff0c;卒于明穆宗隆庆五年&#xff08;公元1571年&#xff09;&#xff0c;享年64岁。他是中国明代著名的散文家、文学家和史学家&#xff0c;其散文风格清…

Python + OpenCV 系列:图像阈值处理

文章目录 引言 1. 阈值处理的基本概念2. OpenCV 中的阈值处理3. 常见的阈值类型3.1 二值化阈值3.2 反向二值化阈值3.3 截断阈值3.4 平滑阈值 4. 自适应阈值5. Otsu’s 阈值法6. 阈值处理的应用场景7. 总结 引言 图像阈值处理是计算机视觉和图像处理中一种非常基础而重要的技术…

计算机网络-Wireshark探索ARP

使用工具 Wiresharkarp: To inspect and clear the cache used by the ARP protocol on your computer.curl(MacOS)ifconfig(MacOS or Linux): to inspect the state of your computer’s network interface.route/netstat: To inspect the routes used by your computer.Brows…

Vue3小兔鲜电商项目

创建项目 npm install 装包

【NLP 12、深度学习15条调参经验】

反正是绚烂&#xff0c;反正是到来 反正是背负慢慢凋残的孤独 耀眼的孤独&#xff0c;义无反顾的孤独 —— 24.12.9 深度学习15条调参经验 1.调参 调参是锦上添花的事&#xff0c;而底线取决于模型的选择和数据的清洗 2.关于model ① 尽量不要自己手写模型&#xff0c;找一…

美畅物联丨视频接入网关如何配置 HTTPS 证书

在安防领域&#xff0c;视频接入网关&#xff08;Video Access Gateway&#xff0c;VAG&#xff09;是视频监控系统的重要组成部分&#xff0c;其职责是把视频数据从前端设备传输至后端服务器。配置HTTPS证书后&#xff0c;可对视频流进行加密传输&#xff0c;避免数据在网络传…