简体   繁体   中英

Convert Long Long Int to int64_t in C by Assignment

The following code converts a value of type long long int to a value of type int64_t by assigning a variable of type long long int to a variable of type int64_t . What are potential problems of this way of converting long long int to int64_t ?

#include <stdio.h>
#include <stdint.h>

int main (void) {

    long long int num = 9223372036854775807; // 2^63-1
    int64_t num64_t = num;
    
    printf("%lld\n", num64_t);

    return 0;
  
}

One problem could be that the ISO/IEC 9899:1999 standard specifies on p. 22, § 5.2.4.2.1, that the range of long long int is at least ±2^63-1, while the int64_t type has exactly 64 bits width. Could it be that on some machines values of type long long int are stored by using more than 64 bits? This could cause the above program to crash if the value of num would be bigger than 2^63-1 or smaller than -(2^63-1) because num64_t has only 64 bits available. If this is a problem: Are there others? More generally: Is the above method a safe way to convert a value of type long long int to a value of type int64_t ? If not, how could these problems be avoided?

One problem could be that the ISO/IEC 9899:1999 standard specifies on p. 22, § 5.2.4.2.1, that the range of long long int is at least ±2^63-1, while the int64_t type has exactly 64 bits width.

C99 is obsolete, but the more recent versions of the standard (current is C2017) specify the same thing. And yes, that is a potential problem: not so much the sizes of the types, but their ranges of representable values. If you try to assign a long long int value to an int64_t , and that value is not representable as an int64_t , then either the result is implementation-defined or an implementation-defined signal is raised.

Could it be that on some machines values of type long long int are stored by using more than 64 bits?

Yes, that is possible. And also that the range of long long int is wider than the range of int64_t .

This could cause the above program to crash if the value of num would be bigger than 2^63-1 or smaller than -(2^63-1) because num64_t has only 64 bits available.

Yes, if the result is to raise a signal then that could cause the program to crash. It is more typical, however, that the conversion succeeds but (necessarily) produces a different value in the assignee. That's arguably worse, as you are not immediately alerted to the problem.

If this is a problem: Are there others? More generally: Is the above method a safe way to convert a value of type long long int to a value of type int64_t ?

Assignment of an integer value to an object of any integer type automatically converts the value to the target type. Conversions from one integer type to another are allowed and value-preserving when the value assigned is representable in the target type. Although not relevant to your specific case, such conversions are allowed and well defined if the target type is unsigned, even if the original value is not representable in the unsigned target type. I have already described the effects in all other cases.

That is, no, there are no issues to be concerned about beyond the consequences already described of trying to assign an out-of-range value to the target signed integer object.

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.

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