简体   繁体   English

C++ 为什么在这里将 uint16_t 隐式转换为 int?

[英]C++ Why is the uint16_t being implicitly cast to int here?

I have this line in my code:我的代码中有这一行:

Locus locus({track.chrom, track.begin, LOCUS_TYPE_INNER, it->left, it->right, it->gc / 5, true}) ;

The it is an iterator which points to one of these: it是一个迭代器,指向以下之一:

struct SimpleKmer {
    uint64_t kmer ;
    uint64_t left ;
    uint64_t right ;
    uint16_t gc ;
};

All the fields are unsigned.所有字段均未签名。 When compiling I get the following error:编译时出现以下错误:

warning: narrowing conversion of ‘(int)(((short unsigned int)((int)it.KmerIterator::operator->()->SimpleKmer::gc)) / 5)’ from ‘int’ to ‘uint16_t’ {aka ‘short unsigned int’} inside { } [-Wnarrowing]

This concerns the it->gc / 5 argument being passed to Locus .这涉及传递给Locusit->gc / 5参数。 The corresponding field in Locus is also a uint16_t . Locus的相应字段也是uint16_t

I'm confused as to why the compiler is doing all these implicit casts here.我很困惑为什么编译器在这里进行所有这些隐式转换。 If I change the expression to it->gc / uint16_t(5) I still get the same error which raises the question of why the compiler is casting things to integer when they are the same type.如果我将表达式更改为it->gc / uint16_t(5)我仍然得到同样的错误,这引发了一个问题,当它们是相同类型时,编译器为什么将它们强制转换为整数。

Does the division operator automatically cast arguments to int?除法运算符是否自动将参数转换为 int?

Does the division operator automatically cast arguments to int?除法运算符是否自动将参数转换为 int?

Promote, not cast, but yes.宣传,而不是演员,但是是的。 See Implicit conversions: Integral promotion on cppreference.com:请参阅 cppreference.com 上的隐式转换:积分促销

In particular, arithmetic operators do not accept types smaller than int as arguments , and integral promotions are automatically applied after lvalue-to-rvalue conversion, if applicable.特别是, 算术运算符不接受小于int类型作为参数,并且在左值到右值转换后自动应用整数提升(如果适用)。 This conversion always preserves the value.此转换始终保留该值。

You are trying to assign the result of it->gc / 5 to a uint16_t field, which normally isn't a problem during an assignment, eg:您正在尝试将it->gc / 5的结果分配给uint16_t字段,这在分配过程中通常不是问题,例如:

uint16_t field;
field = it->gc / 5; // OK

However, such a narrowing conversion from a larger integer to a smaller integer is not allowed inside of a brace initializer:但是,在大括号初始化器内部不允许从较大整数到较小整数的这种缩小转换:

List Initialization 列表初始化

Narrowing conversions缩小转化范围

list-initialization limits the allowed implicit conversions by prohibiting the following:列表初始化通过禁止以下内容来限制允许的隐式转换:

  • ... ...

  • conversion from integer or unscoped enumeration type to integer type that cannot represent all values of the original, except where source is a constant expression whose value can be stored exactly in the target type从整数或无作用域枚举类型到不能表示原始所有值的整数类型的转换,除非源是一个常量表达式,其值可以准确地存储在目标类型中

  • ... ...

A uint16_t can't represent all of the values of an int , hence the error. uint16_t不能表示int所有值,因此出现错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM