Definition of int64_t

151,433

Solution 1

a) Can you explain to me the difference between int64_t and long (long int)? In my understanding, both are 64 bit integers. Is there any reason to choose one over the other?

The former is a signed integer type with exactly 64 bits. The latter is a signed integer type with at least 32 bits.

b) I tried to look up the definition of int64_t on the web, without much success. Is there an authoritative source I need to consult for such questions?

http://cppreference.com covers this here: http://en.cppreference.com/w/cpp/types/integer. The authoritative source, however, is the C++ standard (this particular bit can be found in §18.4 Integer types [cstdint]).

c) For code using int64_t to compile, I am including <iostream>, which doesn't make much sense to me. Are there other includes that provide a declaration of int64_t?

It is declared in <cstdint> or <cinttypes> (under namespace std), or in <stdint.h> or <inttypes.h> (in the global namespace).

Solution 2

int64_t is guaranteed by the C99 standard to be exactly 64 bits wide on platforms that implement it, there's no such guarantee for a long which is at least 32 bits so it could be more.

§7.18.1.3 Exact-width integer types 1 The typedef name intN_t designates a signed integer type with width N , no padding bits, and a two’s complement representation. Thus, int8_t denotes a signed integer type with a width of exactly 8 bits.

Solution 3

int64_t is typedef you can find that in <stdint.h> in C

Solution 4

An int64_t should be 64 bits wide on any platform (hence the name), whereas a long can have different lengths on different platforms. In particular, sizeof(long) is often 4, ie. 32 bits.

Solution 5

My 2 cents, from a current implementation Point of View and for SWIG users on k8 (x86_64) architecture.

Linux

First long long and long int are different types but sizeof(long long) == sizeof(long int) == sizeof(int64_t)

Gcc

First try to find where and how the compiler define int64_t and uint64_t

grepc -rn "typedef.*INT64_TYPE" /lib/gcc
/lib/gcc/x86_64-linux-gnu/9/include/stdint-gcc.h:43:typedef __INT64_TYPE__ int64_t;
/lib/gcc/x86_64-linux-gnu/9/include/stdint-gcc.h:55:typedef __UINT64_TYPE__ uint64_t;

So we need to find this compiler macro definition

gcc -dM -E -x c /dev/null | grep __INT64                 
#define __INT64_C(c) c ## L
#define __INT64_MAX__ 0x7fffffffffffffffL
#define __INT64_TYPE__ long int

gcc -dM -E -x c++ /dev/null | grep __INT64
#define __INT64_C(c) c ## L
#define __INT64_MAX__ 0x7fffffffffffffffL
#define __INT64_TYPE__ long int

Clang

clang -dM -E -x c++ /dev/null | grep INT64_TYPE
#define __INT64_TYPE__ long int
#define __UINT64_TYPE__ long unsigned int

Clang, GNU compilers:
-dM dumps a list of macros.
-E prints results to stdout instead of a file.
-x c and -x c++ select the programming language when using a file without a filename extension, such as /dev/null

Ref: https://web.archive.org/web/20190803041507/http://nadeausoftware.com/articles/2011/12/c_c_tip_how_list_compiler_predefined_macros

note: for swig user, on Linux x86_64 use -DSWIGWORDSIZE64

MacOS

On Catalina 10.15 IIRC

Clang

clang -dM -E -x c++ /dev/null | grep INT64_TYPE
#define __INT64_TYPE__ long long int
#define __UINT64_TYPE__ long long unsigned int

Clang:
-dM dumps a list of macros.
-E prints results to stdout instead of a file.
-x c and -x c++ select the programming language when using a file without a filename extension, such as /dev/null

Ref: https://web.archive.org/web/20190803041507/http://nadeausoftware.com/articles/2011/12/c_c_tip_how_list_compiler_predefined_macros

note: for swig user, on macOS x86_64 don't use -DSWIGWORDSIZE64

Visual Studio 2019

First sizeof(long int) == 4 and sizeof(long long) == 8

in stdint.h we have:

#if _VCRT_COMPILER_PREPROCESSOR

typedef signed char        int8_t;
typedef short              int16_t;
typedef int                int32_t;
typedef long long          int64_t;
typedef unsigned char      uint8_t;
typedef unsigned short     uint16_t;
typedef unsigned int       uint32_t;
typedef unsigned long long uint64_t;

note: for swig user, on windows x86_64 don't use -DSWIGWORDSIZE64

SWIG Stuff

First see https://github.com/swig/swig/blob/3a329566f8ae6210a610012ecd60f6455229fe77/Lib/stdint.i#L20-L24 so you can control the typedef using SWIGWORDSIZE64 but...

now the bad: SWIG Java and SWIG CSHARP do not take it into account

So you may want to use

#if defined(SWIGJAVA)
#if defined(SWIGWORDSIZE64)
%define PRIMITIVE_TYPEMAP(NEW_TYPE, TYPE)
%clear NEW_TYPE;
%clear NEW_TYPE *;
%clear NEW_TYPE &;
%clear const NEW_TYPE &;
%apply TYPE { NEW_TYPE };
%apply TYPE * { NEW_TYPE * };
%apply TYPE & { NEW_TYPE & };
%apply const TYPE & { const NEW_TYPE & };
%enddef // PRIMITIVE_TYPEMAP
PRIMITIVE_TYPEMAP(long int, long long);
PRIMITIVE_TYPEMAP(unsigned long int, long long);
#undef PRIMITIVE_TYPEMAP
#endif // defined(SWIGWORDSIZE64)
#endif // defined(SWIGJAVA)

and

#if defined(SWIGCSHARP)
#if defined(SWIGWORDSIZE64)
%define PRIMITIVE_TYPEMAP(NEW_TYPE, TYPE)
%clear NEW_TYPE;
%clear NEW_TYPE *;
%clear NEW_TYPE &;
%clear const NEW_TYPE &;
%apply TYPE { NEW_TYPE };
%apply TYPE * { NEW_TYPE * };
%apply TYPE & { NEW_TYPE & };
%apply const TYPE & { const NEW_TYPE & };
%enddef // PRIMITIVE_TYPEMAP
PRIMITIVE_TYPEMAP(long int, long long);
PRIMITIVE_TYPEMAP(unsigned long int, unsigned long long);
#undef PRIMITIVE_TYPEMAP
#endif // defined(SWIGWORDSIZE64)
#endif // defined(SWIGCSHARP)

So int64_t aka long int will be bind to Java/C# long on Linux...

Share:
151,433

Related videos on Youtube

clstaudt
Author by

clstaudt

Updated on February 26, 2020

Comments

  • clstaudt
    clstaudt about 4 years

    I am new to C/C++, so I have a couple of questions about a basic type:

    a) Can you explain to me the difference between int64_t and long (long int)? In my understanding, both are 64 bit integers. Is there any reason to choose one over the other?

    b) I tried to look up the definition of int64_t on the web, without much success. Is there an authoritative source I need to consult for such questions?

    c) For code using int64_t to compile, I am currently including <iostream>, which doesn't make much sense to me. Are there other includes that provide a declaration of int64_t?

    • David Heffernan
      David Heffernan over 11 years
      On my compiler, sizeof(long) == 4
    • PlasmaHH
      PlasmaHH over 11 years
      there are many places where longs are not 64bit... and have you tried looking up some documentation about in64_t like the one on cppreference.com?
    • PlasmaHH
      PlasmaHH over 11 years
      @DavidHefernan: That could still be 64bits ;)
    • cdarke
      cdarke over 11 years
      All you can say about a long is that it is not shorter than an int.
    • sasha.sochka
      sasha.sochka over 10 years
      Cdarke, not only that, you can also say that it's at least 32 bits
    • Luaan
      Luaan almost 9 years
      @sasha.sochka Well, to be more precise, it says that its range is [−2147483647,+2147483647]. Impossible to squeeze under 32-bits, but...
  • Steve Jessop
    Steve Jessop over 11 years
    And for connoisseurs of the standard: int64_t is guaranteed to use 2's complement representation and have no padding bits, and is optional (although it's required to exist if the implementation has a standard type that fits the bill). long int guarantees neither and is always required to exist. And when the C++11 standard refers to "the C standard" in 18.4, it means C99.
  • Greg
    Greg over 6 years
    @SteveJessop Why would someone use int64_t over long int and vice versa?
  • Steve Jessop
    Steve Jessop over 6 years
    @Dave: between those two, the difference that most commonly influences the decision is that long int might only be 32 bits. So if you want to store numbers bigger than 2 billion, and you have to choose between those two, then obviously choose int64_t. For the vice-versa part it's trickier, because long int doesn't have very many compelling guaranteed properties which int64_t lacks. It is guaranteed to exist, though, which int64_t is not. And when you're writing non-portably and know the sizes, if long int is the size you want then just use it and get on with your life.
  • Andrew Henle
    Andrew Henle about 4 years
    First long long and long int are different types but sizeof(long long) == sizeof(long int) == sizeof(int64_t) Oh? Try compiling with -m32....
  • Mizux
    Mizux about 4 years
    @AndrewHenle sorry it was implicitly targeted to k8 architecture host development, otherwise you won't have any swig issue for 32bits