- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我和我的同事就十六进制表示的文字后的 U
后缀存在一些争论。请注意,这不是关于此后缀的含义或它的作用的问题。我在这里找到了其中的几个主题,但我还没有找到我的问题的答案。
一些背景信息:
我们正在努力制定一套我们都同意的规则,并从那时起将其用作我们的风格。我们有一份 2004 Misra C 规则的副本,并决定以此为起点。我们对完全符合 Misra C 不感兴趣;我们正在精心挑选我们认为最能提高效率和稳健性的规则。
上述指南中的规则 10.6 规定:
A “U” suffix shall be applied to all constants of unsigned type.
我个人认为这是一个很好的规则。它需要很少的努力,看起来比显式转换更好,并且更明确地显示了常量的意图。对我来说,将它用于所有无符号常量是有意义的,而不仅仅是数字,因为通过允许异常不会强制执行规则,尤其是对于常量的常用表示。
然而,我的同事认为十六进制表示不需要后缀。主要是因为我们几乎只使用它来设置微 Controller 寄存器,而将寄存器设置为十六进制常量时,符号无关紧要。
我的问题
我的问题不是关于谁对谁错的问题。它是关于找出是否存在后缀的缺失或存在会改变操作结果的情况。有没有这样的情况,还是一致性的问题?
编辑:澄清;特别是关于通过为它们分配十六进制值来设置微 Controller 寄存器。在这种情况下,后缀会有所不同吗?我感觉不会例如,飞思卡尔处理器专家将所有寄存器分配生成为无符号。
最佳答案
在所有十六进制常量上附加一个 U
后缀会使它们如您已经提到的那样无符号。当这些常量与有符号值一起用于操作时,尤其是比较时,这可能会产生不良副作用。
这是一个病态的例子:
#define MY_INT_MAX 0x7FFFFFFFU // blindly applying the rule
if (-1 < MY_INT_MAX) {
printf("OK\n");
} else {
printf("OOPS!\n");
}
有符号/无符号转换的 C 规则是精确指定的,但有点违反直觉,所以上面的代码确实会打印 OOPS
。
MISRA-C 规则非常精确,因为它规定“U”后缀应应用于所有无符号类型的常量。无符号 一词具有深远的影响,事实上,大多数常量实际上不应该被认为是无符号的。
此外,C 标准在十进制和十六进制常量之间做了细微的区别:
int
和更大类型的相同大小的有符号整数类型,则它被认为是无符号的。这意味着在 32 位 2 的补码系统上,2147483648
是一个 long
或一个 long long
而 0x80000000
是一个 unsigned int
。在这种情况下,附加 U
后缀可能会使这一点更加明确,但避免潜在问题的真正预防措施是强制编译器完全拒绝有符号/无符号比较:gcc -Wall -Wextra -Werror
或 clang -Weverything -Werror
是救命稻草。
以下是它的糟糕程度:
if (-1 < 0x8000) {
printf("OK\n");
} else {
printf("OOPS!\n");
}
上面的代码应该在 32 位系统上打印 OK
,在 16 位系统上打印 OOPS
。更糟糕的是,嵌入式项目使用过时的编译器仍然很常见,这些编译器甚至没有为这个问题实现标准语义。
对于您的具体问题,微处理器寄存器的定义值专门用于通过赋值设置它们(假设这些寄存器是内存映射的),根本不需要 U
后缀。寄存器左值应具有无符号类型,十六进制值将根据其值是有符号还是无符号,但操作将进行相同。设置有符号数或无符号数的操作码在您的目标架构和我见过的任何架构上都是相同的。
关于c - 保护十六进制文字后的 "U"后缀,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45621041/
这似乎是一个愚蠢的问题,但为什么在许多语言中存在 ++ 和 -- 运算符的前缀和后缀版本,但是没有类似 += 或 -= 等其他运算符的前缀/后缀版本?例如,如果我能写出这段代码: myArray[x+
我需要链接到第三方预建共享库。在 Windows 上,这意味着与 Third_party.lib 链接,在 Linux/Android 上,这意味着与 libThird_party.so 链接。所以为
我正在学习 C++ 中的运算符重载。原始后缀++ 的特性是它的优先级低于赋值运算符。例如,int i=0, j=0; i=j++; cout using namespace std; class V
如何在文本区域中添加每行前缀.. 示例: 这是文本区域的内容: hello124 我想为每一行添加一个 [b] 前缀和后缀,这样当我点击一个按钮时,结果将是: [b]hello[/b] [b]124[
背景:在传统的逆波兰表示法中,所有运算符都必须具有固定长度,这使得 RPN 可以很容易地被代码评估和操作,因为每个标记、表达式和子表达式都是“自包含”的,以至于人们可以盲目地替换 y在 x y *为
我有以下旨在修改日期格式的Javascript,但是我想添加原始日期或后缀,例如“st”,“nd”,“rd”,“th”到每个结束日期编号。例如,假设我们当前的日期设置为 4 月 28 日,但我想将日期
我想制定一个 header 检查规则来添加回复并将“发件人”更改为“不回复”。我将它用于某种扩散列表地址 我试过这个正则表达式代码,但它不起作用: if !/^From:(.+@myserver\.f
我想改变数据框的列内容,以便单元格内容以列名作为前缀: > x x VarX VarY 1 A C 2 B D 3 A C 4 B D > x$V
当我执行 ipconfig/all 时,我看到 DNS 后缀搜索列表。我需要从 java 中检索该值。有谁知道如何获得它或它从哪里来? 最佳答案 DNS 后缀列表读取自 HKLM\SYSTEM\Cur
当您编写一个包含大量类的应用程序时,您是否为类名使用了前缀/后缀?还是我应该只依赖我已经定义的 namespace ? 在我的例子中,我有这样的类: Blur Contrast Sharpen Inv
大多数浏览器会像这样显示有序列表: 1. foo 2. bar 3. baz 有没有办法更改编号以改为使用前缀: #1 foo #2 bar #3 baz 最佳答案 这是我能想到的最好的,你只在 Fi
我需要批量重命名多个图像,并希望使用父目录作为基本名称。为防止一个覆盖另一个,必须添加后缀。重命名过程的顺序必须遵循文件的时间戳。因为“第一个”文件是我正在使用它的网站的特色图片。 树: └── ma
我试图使用 sed 替换文件中的一些字符串,但遇到了一个问题。 我有以下字符串: TEMPLATE_MODULE TEMPLATE_SOME_ERR TEMPLATE_MORE_ERR 我想用一些字符
我对后缀/前缀运算符的优先级 和关联性 感到困惑。 一方面,当我阅读 K&R 书时,它指出: (*ip)++ The parentheses are necessary in this last ex
我有一个具有以下结构的图 V = {A1, A2, A3, A4, A5, .., An} E = {E1, E2, E3, E4, .., Ek} 现在我们定义A1的后缀: S(A1) = {All
这是解释性代码。语言是Java,代码使用Android。 fg.setTextSize(height*0.50f); //<-'f' is in the brackets 或 @Override pr
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 9 年前。 Improve this
我正在编写自己的数组类作为练习。因为,我读到非成员函数实际上在某些方面比成员函数更好。( Scott Meyers ) 我正在尝试编写尽可能多的运算符重载作为非成员函数。运算符重载 + , - 作为非
谁能解释一下关于 C 编程语言的中缀、后缀和前缀表示法是什么? 最佳答案 这是对 three terms, and how they apply 的一个很好的讨论. C 语言几乎到处都使用中缀表示法。
我有这种情况:我需要在输入文本字段 (html) 中添加引号而不更改输入的值。我正在使用 angular,所以我使用 ngModel,它看起来像这样 我希望输入字段显示“{{data}} 中的任何内
我是一名优秀的程序员,十分优秀!