【问题标题】:Why implicit conversion occurs for addition between unsigned char?为什么无符号字符之间的加法会发生隐式转换?
【发布时间】:2017-08-04 16:17:51
【问题描述】:

GCC 警告此代码:

unsigned char i = 1;
unsigned char j = 2;
i += j;

说:

warning: conversion to 'unsigned char' from 'int' may alter its value [-Wconversion]
   i += j;
        ^

似乎j 隐式转换为int
为什么添加同类型变量会发生隐式转换?

【问题讨论】:

  • 这就是 C 的工作原理。由于历史原因以效率为目标,存在对字长有符号整数的隐式转换。
  • 正确的说法是隐式转换。 Cast 表示程序员使用了运算符(type),因此它始终是显式的。强制转换会强制转换,但在没有转换时也会发生转换。
  • @Lundin 已修复。谢谢。

标签: c integer-promotion compound-assignment


【解决方案1】:

这是 C11 草案标准在 §5.1.2.3(第 15 页)中(几乎)对这种情况所说的话:

示例 2

在执行片段时

char c1, c2;
/* ... */
c1 = c1 + c2;

“整数提升”要求抽象机 将每个变量的值提升为int大小,然后将两者相加 ints 并截断总和。如果可以添加两个chars 在没有 §5.1.2.3 环境 15 ISO/IEC 9899:201x 委员会草案的情况下完成 — 2011 年 4 月 12 日 N1570 溢出,或用溢出包装静默到 产生正确的结果,实际执行只需要产生 结果相同,可能会省略促销活动。

所以,它已经完成,因为标准要求它完成。如果您查看生成的代码,编译器很可能(非常)足够聪明,实际上根本不进行转换。

【讨论】:

    【解决方案2】:

    C 要求整数提升,引用 C11 N1570/6.3.1.1p2

    可以在表达式中使用 int 或 unsigned int 的任何地方都可以使用以下内容:

    • 具有整数类型(int 或 unsigned int 除外)的对象或表达式,其整数转换等级小于或等于 int 和 unsigned int 的等级。

    如果 int 可以表示原始类型的所有值(受宽度限制,对于位域),则该值将转换为 int

    因此,您的 unsigned char 变量用于此类表达式并因此转换为 int,因为 i += j 在功能上等同于 i = i + j

    如果您确定结果在unsigned char 的范围内,那么只需在分配之前对加法的结果应用强制转换,如下所示:

    i = (unsigned char)(i + j)
    

    【讨论】:

    • 这可行,但我认为在这种情况下 char 数据类型使用不当。我的意思是为什么首先要将用于文字 12 的存储声明为 chars?如果存储位置要同时保存整数和字符,则可以轻松使用整数类型,因为字符使用较小的存储空间。
    • @Lym - 一个原因是空间考虑。这不是您在完整的托管系统中经常考虑的事情,但是对于小的偏移量,您可能会觉得有义务选择他们可以选择的最小类型。 (当然uint8_t 是更好的选择)。
    • 如果您不介意我的提问,您是否曾经遇到过这种情况或阅读过采用这种方法的代码。在我看来,由于截断而愿意丢失一些数据在任何情况下都是一个坏主意。只是在寻找案例研究。
    • @Lym - 我本人?我没有使用小于整数的数据类型。但是我已经阅读了足够多的有关嵌入式编程的内容,以了解当您的可用空间严重受限时可能需要考虑的不同因素。
    • 我想我很好奇的另一件事是,当一个转换为较低类型的行为是否被定义时,类似于 [stackoverflow.com/questions/6752567/… 看起来像这样。谢谢你的解释。
    猜你喜欢
    • 2017-11-09
    • 2011-11-08
    • 1970-01-01
    • 2017-04-18
    • 1970-01-01
    • 2013-01-05
    • 2013-07-23
    • 2019-04-10
    • 2020-12-17
    相关资源
    最近更新 更多