Reputation: 848
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:
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
. The corresponding field in Locus
is also a 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.
Does the division operator automatically cast arguments to int?
Upvotes: 0
Views: 1238
Reputation: 595971
Does the division operator automatically cast arguments to int?
Promote, not cast, but yes. See Implicit conversions: Integral promotion on 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. 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:
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:
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.
Upvotes: 4