MISRA C2012学习笔记(7)-Rules 8.12

news2024/11/28 6:48:28

文章目录

    • 8.12 表达式(Expressions)
      • Rule 12.1 表达式中运算符的优先级应明确
      • Rule 12.2 移位运算符的右操作数应在零到比左操作数基本类型的位宽度小一的范围内
      • Rule 12.3 不得使用逗号(,)运算符
      • Rule 12.4 常量表达式的求值不应导致无符号整数的回绕

8.12 表达式(Expressions)

Rule 12.1 表达式中运算符的优先级应明确

等级:建议

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

适用:C90,C99

展开:

下表用于此规则的定义。
在这里插入图片描述
选择该表中使用的优先级是为了简明地描述规则。它们不一定与其他操作符优先级描述中可能遇到的相同。

出于本规则的目的,表达式的优先级是位于该表达式解析树根的元素(操作数或操作符)的优先级

例如:表达式a << b + c的解析树可以表示为:
在这里插入图片描述
该解析树的根元素是’<<',因此表达式的优先级为10

此规则提供以下建议:

•sizeof操作符的操作数应该用圆括号括起来;

•优先级在2到12范围内的表达式应该在具有这两个优先级的操作数周围加上括号:

-优先级小于13,并且

-优先级大于表达式的优先级

原理: C语言的运算符数量很多,并且它们的相对优先级并不直观。这会导致经验不足的程序员犯错误。使用括号使运算符优先级明确,可以消除程序员的期望与事实不符的可能性。这也使代码的审阅者或维护者可以清楚地了解程序员的原始意图。

众所周知,过度使用括号会使代码混乱并降低其可读性。这条规则的目的是在那些因为括号太多或太少而难以理解的代码之间达成妥协。

示例:

下面的示例显示具有单目或后缀运算符的表达式,其操作数是主表达式或顶级运算符具有优先级 15 的表达式。

a[ i ]->n;      /* 合规 - 无需写成 (a[i])->n,优先级为15          */
*p++;           /* 合规 - 无需写成 *(p++),优先级为14                */
sizeof x + y;   /* 违规 - 应写成 sizeof(x) + y 或 sizeof(x + y)                                */

以下示例显示了包含具有相同优先级的运算符的表达式。 所有这些都是合规的,但取决于 a,b 和 c 的类型,具有多个运算符的任何表达式都可能违反其他规则。

相同指的是操作数的优先级和表达式的优先级

a + b; 
a + b + c; 
(a + b) + c; 
a + (b + c); 
a + b - c + d; 
(a + b) - (c + d); 

以下示例列举了各种混合运算符表达式:

/* 合规 - 无需写成 f((a + b), c) */ 
x = f (a + b, c); 
 
 /* 违规 
* 条件运算符(优先级2)的操作数为: 
* == 优先级8 需要括号 
* a 优先级16 不需要括号 
* - 优先级11 需要括号 
*/ 
x = a == b ? a : a - b; 
 
 /* 合规 */ 
x = (a == b) ? a : (a - b); 
 
 /* 合规 
* << 运算符(优先级10)的操作数为: 
* a 优先级16 不需要括号 
* b+c的优先级为11,大于10,需要括号(原文中注释的不对) 
*/ 
x = a << (b + c); 
 
 /* 合规 
* && 运算符(优先级4)的操作数为: 
* a 优先级16 不需要括号 
* && 优先级4 优先级相同 不需要括号 
*/ 
if (a && b && c) 
{ 
} 
 
 /* 合规 
* && 运算符(优先级4)的操作数为: 
* defined(X) 优先级14 不需要括号 
* x+y 优先级11大于10,需要括号 >Z优先级9,需要括号(原文中注释的不对) 
*/ 
#if defined(X) && ((X + Y) > Z) 

/* 合规 
* && 运算符(优先级4)的操作数为: 
* !defined(X) 优先级14 不需要括号 
* defined(Y) 优先级14 不需要括号 
* ! 运算符(优先级14)的操作数为: 
* defined(X) 优先级14 优先级相同 不需要括号 
*/ 
#if !defined(X) && defined(Y)

注意:该规则不要求将,操作符的操作数加括号。规则12.3禁止使用,操作符。

x = a, b; /* 合规 - 解析为 (x = a), b */ 

解读:对于运算符的优先级,一般很难记得清楚,特别是在逻辑运算和加减乘除一起作为判断时,所以在指定的操作数之间加上括号,可以防止优先级导致的意外运算与操作,同时也更便于自己或其他人理解。这个规则还是很有必要执行的

Rule 12.2 移位运算符的右操作数应在零到比左操作数基本类型的位宽度小一的范围内

等级:必要

分析:不可判定,系统范围

适用:C90,C99

原理:

右操作数为负或大于或等于左操作数的宽度的行为未定义。

举例来说,如果左移或右移的左操作数是 16 位整数,则确保仅将其移位 0 到 15 之间的数字非常重要。

有关移位运算符的基本类型和基本类型的限制的说明,请参见第 8.10 节。

我们有多种方法可以确保遵守此规则。最简单的方法是将右操作数设为常数(然后可以静态检查其值)。

另一种方法是使用无符号整数类型以确保操作数为非负数,然后仅需要检查上限(在运行时动态检查或通过评审(review)检查)。否则,将需要检查两个限制

示例:

u8a = u8a << 7; /* 合规 */ 
u8a = u8a << 8; /* 违规 ,uint8左移8位导致无意义*/ 
u16a = (uint16_t)u8a << 9; /* 合规 */ 

为便于理解以下示例,应注意,1u 的基本类型是 unsigned char,而 1UL 的基本类型是 unsigned long。

1u << 10u;                      /* 违规 */
( uint16_t ) 1u << 10u;         /* 合规 */
1UL << 10u;                     /* 合规 */

解读:移位运算应该指定长度,且长度不能高于左操作数的数据类型,否则移位无意义,代码是可能异常的。这个规则也需要执行

Rule 12.3 不得使用逗号(,)运算符

等级:建议

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

适用:C90,C99

原理:

使用逗号运算符通常不利于代码的可读性,并且通常可以通过其他方式实现相同的效果。
示例:

f((1, 2), 3); /* 违规 - 究竟有几个形参? */

以下示例违背 了此规则和其他规则:

for (i = 0, p = &a[0]; i < N; ++i, ++p) 
{ 
}

解读:逗号运算符不应该使用,无意义

Rule 12.4 常量表达式的求值不应导致无符号整数的回绕

等级:建议

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

适用:C90,C99

展开:
此规则适用于满足常量表达式约束的表达式,无论它们是否出现在需要常量表达式的上下文中。

如果未对表达式求值(例如,它出现在逻辑 AND 运算符的右操作数中,而其左操作数始终为 false),则此规则不适用。
原理: 无符号整数表达式不会严格溢出,而是会回绕。 尽管在运行时使用模运算可能有充分的理由,但是在编译时故意使用模运算的可能性较小。
示例:与 case 标签关联的表达式必须是常量表达式。如果在对 case 表达式求值时发生无符号回绕,则可能是无意的。在具有 16 位宽度的 int 类型的计算机上,在下面的示例中,任何大于或等于 65024 的 BASE 值都将导致回绕:

#define BASE 65024u 
 
switch(x ) 
{ 
 case BASE + 0u: 
f(); 
break; 
case BASE + 1u: 
g(); 
break; 
case BASE + 512u: /* 违规 - 会回绕回 0 */ 
h(); 
break; 
} 

预处理指令#if 和#elif 的控制表达式必须是常量表达式。

#if 1u + (0u - 10u) /* 违规 - 因为 (0u - 10u) 会回绕 */

在下面这个示例中,表达式 DELAY + WIDTH 的值为 70000,但是在具有 16 位 int 类型的计算机上,该
值将回绕为 4464。

#define DELAY 10000u 
#define WIDTH 60000u 
void fixed_pulse(void) 
{ 
 uint16_t off_time16 = DELAY + WIDTH; /* 违规 */ 
} 

在下面的合规示例中,此规则不适用于表达式 c +1,因为它访问了对象,因此不满足常量表达式的约束:

const uint16_t c = 0xffffu;
void f ( void )
{
  uint16_t y = c + 1u;   /* Compliant */
}

在下面的示例中,子表达式(0u-1u)导致无符号整数环绕。在 x 的初始化中,不评估子表达式,因此表达式是合规的。但是,在y 的初始化中,可能会对其进行求值,因此表达式违规。

bool_t b; 
 
void g(void) 
{ 
 uint16_t x = (0u == 0u) ? 0u : (0u - 1u); /* 合规 */ 
uint16_t y = b ? 0u : (0u - 1u); /* 违规 */ 
} 

解读:该规则中的wrap-around虽然不是overflow,但本质上还是会导致计算结果异常,之前一直理解的就是溢出,只是说异常的结果是可以计算出来的。该规则有必要执行,不过一般不会犯这种错误

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

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

相关文章

Netty技术全解析:EventLoopGroup类详解

❃博主首页 &#xff1a; 「码到三十五」 &#xff0c;同名公众号 :「码到三十五」&#xff0c;wx号 : 「liwu0213」 ☠博主专栏 &#xff1a; <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关> ♝博主的话 &#xff1a…

VBA技术资料MF174:利用文本框和列表框录入数据

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…

Ubuntu网络连接图标消失了,没网!!!

文章目录 前言Step1&#xff1a;停止网络管理服务Step2&#xff1a;删除网络管理状态文件Step3&#xff1a;打开网络管理 前言 本次记录的事&#xff0c;有一天心血来潮想烧录一下开发板&#xff0c;却发现自己的Ubuntu系统的网络连接图标消失了&#xff0c;也没网了&#xff…

DEBUG:inpyb无法引用本地的py文件

问题 无法import 解决 暂时合并为一个文件 直接执行且测试简单模块可以引用&#xff08;部分复杂文件无法引用&#xff09;结合本程序 应该需要修改不规则的正则表达式 发现部分警告导致程序无法引用&#xff08;而且和环境有关 linux不会&#xff09;

医联体信息平台建设方案PPT(54页)

文章摘要&#xff1a; 医联体信息平台现状当前医联体信息平台存在脱离医疗业务建设的倾向&#xff0c;导致信息孤岛&#xff0c;业务协同困难。 建设存在的问题主要问题包括健康档案无法动态更新和共享&#xff0c;信息系统之间信息共享和协同不足。 医联体信息平台建设方案方…

【Linux】进程间通信及管道详细介绍(上)

前言 本节我们开始学习进程间通信相关的知识&#xff0c;并详细探讨一下管道&#xff0c;学习匿名管道和命名管道的原理和代码实现等相关操作… 目录 1. 进程间通信背景1.1 进程通信的目的&#xff1a; 2 管道的引入&#xff1a;2.1 匿名管道&#xff1a;2.1.1 匿名管道的原理&…

LATEX模板支持中文、目录和段落

\documentclass{ctexart} \usepackage{amsmath,amssymb,amsfonts,hyperref} \usepackage{CJKutf8} \usepackage{enumitem} % 引入宏包 \usepackage [colorlinkstrue] {} \begin{document}\begin{CJK}{UTF8}{gkai}%正文放在此行下与\end{CJK}之间就行\tableofcontents\newpage\s…

【Python】从基础到进阶(四):深入了解Python中的控制流

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 一、引言二、条件语句1. if 语句2. if-else 语句3. if-elif-else 语句4. 嵌套条件语句5. 三元运算符 三、循环语句1. for 循环基本语法使用range() 函数遍历列表、字典和字符串 2. while 循环基本语法无限循环与终止条件 3.…

Python 实现股票指标计算——BBI

BBI (Bull And Bear lndex) - 多空指标 1 公式 3日均价 3日收盘价之和 / 36日均价 6日收盘价之和 / 612日均价 12日收盘价之和 / 1224日均价 24日收盘价之和 / 24BBI (3日均价 6日均价 12日均价 24日均价) / 4 2 数据准备 我们以科创50指数 000688 为例&#xff0c…

使用Vue实现点击页面触发特效

效果描述 在页面上的指定区域内进行点击&#xff0c;则会在页面上显示设置好的随机文本&#xff0c;此文本出现后会执行动画&#xff0c;动画效果为节点在1s之内向右上方移动并在移动的过程中完成180翻转&#xff0c;最后消失。 效果展示 完整代码 <template><div…

Windows 11 Visual Studio 2022 cmake 3.29 CUDA12.5 构建VTK

The Visualization Toolkit (VTK)是一个用于操作和展示科学数据的开源软件&#xff0c;包括了二三维渲染功能。 下载VTK 从官网Download | VTK下载VTK版本&#xff0c;我下载的是9.3.1源代码&#xff0c;在Windows 11上安装。 CMake构建VTK的VS2022工程 生成与安装 分别生成De…

AI智能名片小程序:跨界融合,重塑品牌与顾客的“三度情缘”

在这个信息爆炸、竞争白热化的时代&#xff0c;品牌如何突破重围&#xff0c;与顾客建立超越常规的情感链接&#xff1f;答案或许就藏在那个看似不起眼&#xff0c;实则暗藏玄机的AI智能名片小程序里&#xff01;它不仅是技术的结晶&#xff0c;更是品牌与顾客之间“三度情缘”…

Redis持久化(AOF和RDB)

目录 前言 一.RDB 1.1手动执行 1.2自动执行 二.AOF 2.1重写机制 三.混合持久化 Redis的学习专栏&#xff1a;http://t.csdnimg.cn/a8cvV 前言 持久化&#xff0c;在之前&#xff0c;我们接触这个词汇是在mysql数据库当中的事务四大特性里。 持久性&#xff1a;指一旦事…

探索免费隧道服务:为本地开发提供自定义子域名的解决方案

目录 引言 使用Ngrok进行本地开发 免费替代方案 Localtunnel Serveo Ngrok付费计划&#xff08;有限的免费试用&#xff09; 开源替代方案 SISH 总结 引言 在Web开发中&#xff0c;将本地服务器暴露给互联网进行测试或演示是常见需求。Ngrok等工具因其便捷性而广受欢迎…

【LeetCode】分隔链表

目录 一、题目二、解法完整代码 一、题目 给你一个链表的头节点 head 和一个特定值 x &#xff0c;请你对链表进行分隔&#xff0c;使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你应当 保留 两个分区中每个节点的初始相对位置。 示例 1&#xff1a; 输入&a…

等保-Linux等保测评

等保-Linux等保测评 1.查看相应文件&#xff0c;账户xiaoming的密码设定多久过期 rootdengbap:~# chage -l xiaoming Last password change : password must be changed Password expires : pass…

day5 分布式节点

文章目录 1 流程回顾2 抽象 PeerPicker3 节点选择与 HTTP 客户端4 实现主流程5 main 函数测试。6 QA 本文代码地址&#xff1a; 本文是7天用Go从零实现分布式缓存GeeCache的第五篇。 注册节点(Register Peers)&#xff0c;借助一致性哈希算法选择节点。实现 HTTP 客户端&…

OpenGL-ES 学习(7) ---- VBO EBO 和 VAO

目录 VBO(Vertex Buffer Object)EBO(Element Buffer Object)VAO(Vertex Array Object) VBO(Vertex Buffer Object) EBO(Element Buffer Object) VBO(Vertex Buffer Object) 实际是指顶点缓冲器对象 在 opengl-es 2.0 的编程中&#xff0c;用于绘制图元的顶点数据是从 CPU 传…

LoadRunner-Vugen脚本使用教程

1 使用VuGen录制脚本 1.1新建脚本和解决方案 &#xff08;1&#xff09;打开VuGen&#xff0c;单击【File】→【New Script and Solution】创建项目&#xff0c;弹出Create a New Script对话框。 左侧栏是协议分类&#xff0c;每项含义如下所示&#xff1a; ● Single Pro…

数字通云平台 智慧政务OA PayslipUser SQL注入漏洞复现

0x01 产品简介 数字通云平台智慧政务OA产品是基于云计算、大数据、人工智能等先进技术,为政府部门量身定制的智能化办公系统。该系统旨在提高政府部门的办公效率、协同能力和信息资源共享水平,推动电子政务向更高层次发展。 0x02 漏洞概述 数字通云平台 智慧政务OA Paysli…