Skip to content Skip to sidebar Skip to footer

Is It Safe To Cast Jlong To Long?

I'm developing a native plugin for Android with JNI in C++. I want to print out a jlong value, which is defined as a 64-bit value. Is it safe to cast it directly to a long, or are

Solution 1:

No. Yes.

Java, as you have correctly noticed, defines long as a 64 bit number. C++ does not do that long is only guaranteed to be at least as large as int, so it might as well be a 32-bit number.

However, it so happens that given the combination "Android" + "64 bit", indeed long is a 64-bit integer. That's much different from e.g. Windows where it's still just a 32-bit integer. So, assuming you are writing for 64-bit only, you could stop reading here and now.

But, why the trouble?

C++ borrows the <cstdint> header from C, which defines among others the type int64_t. So you need to use something of which you know is a 64-bit type and you're worried it might not fit?

Well, use a type that is guaranteed to cope with that:

#include<cstdio>using my_jlong = int64_t;

Solution 2:

The minimum range of values the C++ standard requires a long to represent (-2147483647 to 2147483647), which means it could be a 32-bit type. Converting a jlong value to long that exceeds the range of a 32-bit type - if that is what a long is for your target implementation - will yield undefined behaviour.

The minimum required range (-9223372036854775807 to 9223372036854775807) of values that a long long can represent means it is a 64-bit type (or better).

The potential problem results from edge-cases: specifically the extreme (largest representable negative or largest positive values in the types), since 64-bit integral types can represent an even number of values, one of which is zero. This means the number of positive values a 64-bit type can represent is one different (either more or less) than the number of negative values it can represent. If jlong represents a different range of values than a long long (e.g. jlong represents the range -9223372036854775807 to 9223372036854775808, while long long represents -9223372036854775808 to 9223372036854775807) then the result of converting such extreme values can give undefined behaviour.

In short, there no guarantee that a long long will be able to represent exactly the same range of values as a jlong. Practically, you will find most modern target platforms will be alright. However, this was not true of some older systems and (theoretically at least) could change again in future.

If you can guarantee (e.g. through analysis of your Java code) that your jlong never holds one of the offending extreme values that a long long may not be able to represent, then there will be no problem converting to a long long. There will also be no problem if you can guarantee (e.g. by referring to documentation for each target system and C++ compiler) that a long long supports at least the same range of values as a jlong.

You probably would be better off printing using C++ streams (which have insertion operators overloaded for each standard type) than using C I/O (which relies on you getting the format string right).

Post a Comment for "Is It Safe To Cast Jlong To Long?"