I have the uint64_t constants in my C++ program (clang 6.0.1 in QtCreator 4.6.1).
For example:
uint64_t a = 0xffffffffffffffffULL;
The problem is, that I get the following warning in the IDE:
Warning: implicit conversion from 'unsigned long long' to 'uint64_t' (aka 'unsigned long')
I tried also to change it to the following without success :
uint64_t a = UINT64_C(0xffffffffffffffff);
uint64_t a = 0xffffffffffffffffUL;
I have options to compute with C++14 standard and option: -Wconstant-conversion
Checking the types size:
std::cout << "uint64_t " << sizeof (uint64_t) << std::endl;
std::cout << "unsigned long " << sizeof (unsigned long) << std::endl;
std::cout << "unsigned long long " << sizeof (unsigned long long) << std::endl;
Result:
uint64_t 8
unsigned long 8
unsigned long long 8
Any idea how to fix this and why IDE thinks that size conversion is happening?
Edit: I just checked the macro expansion:
define UINT64_C(c) c ## UL
This means that provided example should work, however it doesn't:
uint64_t a = 0xffffffffffffffffUL;
unsigned long long
is at least 64 bits, so it could be a bigger type than uint64_t
I would write (note the use of constexpr because it's a constant):
#include <cinttypes>
#include <limits>
constexpr auto a = std::numeric_limits<std::uint64_t>::max();
And to define a non-max uint64_t
constant in portable way, just remove the ULL
part at the end:
constexpr std::uint64_t b = 0x12345;
This warning is resolved thanks to @hvd comment.
Checked all included header files. For some reason, both stdint.h
and cstdint
were included. I left only the cstdint
. They are probably from different platforms and have different definitions.
The working example:
uint64_t v0 = UINT64_C(0x736f6d6570736575);
The compiler is warning you of an implicit conversion between types that are not guaranteed to be of the same size in C++. A possible fix is to make it explicit:
uint64_t a = static_cast<uint64_t>(0xffffffffffffffffULL);
这是一种方法:
auto a = static_cast<uint64_t>(-1);
The first thing to note here is that you don't need the LL
suffix.
An integer literal automatically will have a type which can hold the number. Check out this table for exact types. The only exception to this rule is if you specify a decimal literal which only fits to unsigned long long int
. Then you need to specify the u
suffix.
Now, the warning can be removed easily with a cast:
uint64_t a = (uint64_t)0xffffffffffffffff;
or if you don't like C cast, then with static_cast
:
uint64_t a = static_cast<uint64_t>(0xffffffffffffffff);
So far, this was the theory, but you have some problems with your compiler/installation. If you have the implicit conversion warning for this:
uint64_t a = 0xffffffffffffffffUL;
where uint64_t
is unsigned long
, then it means that 0xffffffffffffffffUL
actually becomes unsigned long long int
. But it should not be, as sizeof(unsigned long)
is 8 already. This is clearly an impossible situation, if the compiler and installation is correct.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.