【问题标题】:Implicit conversion in c++ for between unsigned types of bit length ie uint8_t,uint16_tc++ 中无符号位长类型之间的隐式转换,即 uint8_t,uint16_t
【发布时间】:2020-10-17 21:06:33
【问题描述】:

我想知道在各种位的无符号整数之间的表达式(即 uint8_t、uint16_t 等)的情况下如何隐式转换工作以及显式避免它的方法。为此,我总结了以下几个案例:

  • 在 uint8_t 加法、减法、乘法、除法的情况下如何进行隐式转换?

    uint8_t A;
    uint8_t B;
    uint16_t C;
    
    C= A+B; (uint8_t + uint8_t )
    C= A-B; (uint8_t + uint8_t )
    C= A*B; (uint8_t + uint8_t )
    C= A/B; (uint8_t + uint8_t )

显式声明是 C= static_castA+B;或 C= static_cast(A+B);. 这是正确的吗? C= static_castA+B; 之间有什么区别吗?还是 C= static_cast(A+B)?

  • 在 unsigned int(使用 U 字面量)和 uint8_t 表达式的情况下,隐式转换如何工作? 重要的顺序之间是否也有区别,即 1UB;(unsined int * uint8_t ) 或 B1U;(uint8_t * uint8_t )

    C= A+1U;(uint8_t + uint8_t )
    C= A-1U;(uint8_t - uint8_t )
    C= 1U*B;(uint8_t * uint8_t )
    C= 1U/B;(uint8_t / uint8_t )

显式转换为 C= static_castA+1U;或 C= static_cast(A+1U); C= static_cast1UB;或 C= static_cast(1UB);. 对吗 这些行之间有什么区别吗?

  • 表达式中的隐式转换如何工作。是否考虑了正常顺序? 表达式的最终类型是什么?

    C= 1U/(A-1U);  (unsigned int / (uint8_t -(unsigned int))
    C= (C-(A/B))/B; (uint8_t -(uint8_t /(unsigned int))/(uint8_t)

在这种情况下 static_cast 应该如何看待?只有第一个变量(1U 或 C)会为其余变量定义 C= static_cast(1U)/(A-1U);

  • 标准函数的隐式转换如何工作

    sizeof(A) returns size_t 
    C=abs(-1*A) returns int in case of int parmaters    

        

显式转换为 C= static_castsizeof(A) 和 C= static_castabs(-1*A)。那是对的吗? 那么 C= static_castabs(-1)*A) 呢?

  • 函数参数的隐式转换如何工作。

    uint16_t sum(uint16_t C1,uint16_t C2);
    C=sum(A,B-1U/2U);           
    C=sum(A,1U/2U-B);

显式转换为 C= sum(static_cast(A),static_cast(B-1U/2U))。对吗?

我在 Opencv 中看到了一个类似于 static_cast 的函数,叫做 saturate_cast。在上述任何一种情况下,它会是一个更好的解决方案吗?

【问题讨论】:

  • 你的问题是什么?
  • The way to avoid 避免什么? The correct approach请定义“正确”。
  • @Cortex:主要是我需要知道表达式中的隐式转换顺序是如何执行的。例如C=1U/(A-1U); (unsigned int / (uint8_t -(unsigned int)) C= (C-(A/B))/B; (uint8_t -(uint8_t /(unsigned int))/(uint8_t)上面的表达式在右边
  • @KamilCuk:我将描述更改为更易于理解。请参阅我上面的评论作为这个问题的简要总结。
  • 我认为一本好书和研究会比 stackoverflow 更能帮助你。

标签: c++ implicit-conversion static-cast explicit-conversion


【解决方案1】:

在 uint8_t 加法、减法、乘法、除法的情况下,隐式转换如何工作?

uint8_t转化排名小于输入 int 并且输入 int 始终可以容纳 uint8_t 的整个值范围,UINT8_MAX 是 255,int 具有 至少 16位。 uint8_t 将在操作员之前通过整体提升提升为intcppreference integral promotionfundamental typescstdint

显式声明是 C= static_castA+B;或 C= static_cast(A+B);。这是正确的吗?

没有。这些不是声明示例,缺少类型说明符。他们使用operator= 为对象C 赋值。 “显式声明”是使用auto 关键字的声明。 cppreference declaration

C= static_castA+B; 有什么区别吗?还是 C= static_cast(A+B)?

是的,在 int 无法容纳 uint16_t 的所有值范围的架构上。在这种特殊情况下,第一个表达式首先将+ 运算符的操作数提升为unsigned int,而第二个表达式使用int 类型进行操作。第二个表达式与C = A + B 相同,因为C 的类型为uint16_t。除了这种特殊情况,在int 可以容纳uint16_t 的所有值范围的架构上,两个操作数都将提升为intC= static_cast<uint16_t>(A+B)C = A + B 相同。

在 unsigned int(使用 U 字面量)和 uint8_t 表达式的情况下,隐式转换如何工作?

首先两个操作数都经历积分提升unsigned int 保留,uint8_t 被提升为 int。然后操作数进行积分转换。因为其中一个操作数是unsigned 并且两个操作数具有相同的转换等级,所以将有符号操作数转换为无符号类型,即。 int 转换为 unsigned intarithmetic operators and arithmetic conversions

重要的顺序之间是否也有区别,即1U*B;(unsined int * uint8_t )B*1U;(uint8_t * uint8_t )

不,操作数的顺序无关紧要。

显式转换为 C= static_castA+1U;或 C= static_cast(A+1U); C= static_cast1UB;或 C= static_cast(1UB);。对吗?这些行之间有什么区别吗?

static_cast<uint16_t>1UB 是语法错误。 C = static_cast<declatype(C)>(expr) 始终等于 C = expr

表达式的隐式转换如何工作。是否考虑正常顺序?

我不明白什么是“正常订单”。操作数和表达式根据它们的优先级进行计算。

表达式的最终类型是什么?

 C= 1U/(A-1U);  (unsigned int / (uint8_t -(unsigned int))

operator=右侧的表达式是unsigned int类型的右值。

 C= (C-(A/B))/B; (uint8_t -(uint8_t /(unsigned int))/(uint8_t)

operator=右侧的表达式是unsigned int类型的右值。

在这种情况下 static_cast 应该如何?

像其他任何地方一样static_cast<type>(expr)

只有第一个变量(1U 或 C)会定义其余的 C= static_cast(1U)/(A-1U);

每个运算符分别计算其操作数,一次计算一个或两个表达式。评估(以及提升)的顺序是根据运算符的优先级排序的。 order of evaluationprecedence and associativity

标准函数的隐式转换如何工作?

根据整数促销规则,与任何其他类型一样。 size_t 只是实现定义的无符号整数类型。

显式转换为 C= static_castsizeof(A) 和 C= static_castabs(-1*A)。对吗?

两个表达式都是语法错误。这是static_cast<type> ( expression )。大括号是强制性的。答案见上文 - 执行C = static_cast<decltype(C)>(expr) 就等于C = expr

C= static_castabs(-1)*A) 怎么样?

怎么样?

函数参数的隐式转换如何工作。

当参数不是可变参数函数调用中省略号的一部分时,参数将转换为参数类型。

显式转换为 C= sum(static_cast(A),static_cast(B-1U/2U))。对吗?

是的,但是为什么?无论如何,它们都会转换为uint16_t

我在 Opencv 中看到了一个类似于 static_cast 的函数,称为 saturate_cast。在上述任何一种情况下,它会是一个更好的解决方案吗?

“更好”是基于意见和模糊的。这取决于您想要达到的目标。 saturate_cast 是一个simple template,专门处理范围更广的类型,然后是目标范围。在这种情况下,参数将转换为该类型的最大值/最小值。

为了进一步研究,。 c++标准草案is available online

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-19
    • 1970-01-01
    • 1970-01-01
    • 2015-10-09
    • 1970-01-01
    • 2013-07-23
    • 2018-12-10
    • 1970-01-01
    相关资源
    最近更新 更多