int64_t的定义


75

我是C / C ++的新手,所以我对基本类型有几个问题:

a)您可以向我解释int64_tlonglong int)之间的区别吗?据我了解,两者都是64位整数。有什么理由选择一个?

b)我试图int64_t在网上查找的定义,但没有取得太大的成功。我需要咨询有关此类问题的权威信息吗?

c)对于int64_t用于编译的代码,我目前包含<iostream>,这对我来说没有太大意义。还有其他包含提供声明的内容int64_t吗?


4
在我的编译器上,sizeof(long) == 4
David Heffernan

在很多地方,longs不是64位的...您是否尝试过查找有关in64_t的文档,例如cppreference.com上的文档?
PlasmaHH 2012年

3
@DavidHefernan:仍然可能是
64位

所有你能说一个long是,它是不是更短的int
cdarke

Cdarke,不仅如此,您还可以说它至少是32位
sasha.sochka 2013年

Answers:


93

a)您可以向我解释int64_tlonglong int)之间的区别吗?据我了解,两者都是64位整数。有什么理由选择一个?

前者是正好有64位的带符号整数类型。后者是至少32位的有符号整数类型。

b)我试图int64_t在网上查找的定义,但没有取得太大的成功。我需要咨询有关此类问题的权威信息吗?

http://cppreference.com在此处进行了介绍:http : //en.cppreference.com/w/cpp/types/integer。但是,权威来源是C ++标准(可以在§18.4整数类型[cstdint]中找到此特定位)。

c)对于int64_t用于编译的代码,我包括<iostream>,这对我来说没有多大意义。还有其他包含提供声明的内容int64_t吗?

<cstdint>或中<cinttypes>(在namespace下std)或在<stdint.h>或中<inttypes.h>(在全局名称空间中)声明它。


2
对于标准的鉴赏家:int64_t保证使用2的补码表示法并且没有填充位,并且是可选的(尽管如果实现的标准类型符合要求,则必须存在)。long int既不保证也不保证总是存在。当C ++ 11标准在18.4中引用“ C标准”时,表示C99。
史蒂夫·杰索普

1
@SteveJessop为什么有人要使用int64_tover long int,反之亦然?
Greg

@Dave:在这两者之间,最常影响决策的差异是long int可能只有32位。因此,如果您要存储大于20亿的数字,并且必须在这两者之间进行选择,那么显然要选择int64_t。反之亦然,这比较棘手,因为long int没有太多令人信服的有保证的特性int64_t。但是,它保证存在,但事实int64_t并非如此。而且,当您进行非便携式书写并知道尺寸时,如果long int想要的尺寸是,请使用它并继续您的生活。
Steve Jessop

11

int64_tC99标准保证在实现该标准的平台上该宽度恰好是64位long,而对于至少32位的a则没有这样的保证,因此可能会更多。

§7.18.1.3精确宽度的整数类型1 typedef名称intN_t指定一个带符号的整数类型,其宽度为N,没有填充位,并且用二进制补码表示。因此,int8_t表示正整数宽度为8位的有符号整数类型。



3

int64_t在任何平台上都应为64位宽(因此得名),而long在不同平台上可以具有不同的长度。特别是sizeof(long)通常为4,即。32位。


1

从当前实施的观点出发,针对k8(x86_64)架构上的SWIG用户,我的费用为2美分。

的Linux

首先long longlong int是不同的类型,但是sizeof(long long) == sizeof(long int) == sizeof(int64_t)

海湾合作委员会

首先尝试查找编译器在哪里以及如何定义int64_t和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;

所以我们需要找到这个编译器宏定义

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 -dM -E -x c++ /dev/null | grep INT64_TYPE
#define __INT64_TYPE__ long int
#define __UINT64_TYPE__ long unsigned int

Clang,GNU编译器:
-dM转储宏列表。
-E将结果打印到标准输出而不是文件。
-x c-x c++在使用不带文件扩展名的文件时选择编程语言,例如/dev/null

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

注:对于swig用户,在Linux x86_64上使用 -DSWIGWORDSIZE64

苹果系统

在Catalina 10.15 IIRC上

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转储宏列表。
-E将结果打印到标准输出而不是文件。
-x c-x c++在使用不带文件扩展名的文件时选择编程语言,例如/dev/null

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

注意:对于Swig用户,在macOS x86_64上不要使用-DSWIGWORDSIZE64

Visual Studio 2019

首先 sizeof(long int) == 4sizeof(long long) == 8

stdint.h我们有:

#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;

注意:对于Swig用户,在Windows x86_64上不要使用-DSWIGWORDSIZE64

猪的东西

首先请参阅 https://github.com/swig/swig/blob/3a329566f8ae6210a610012ecd60f6455229fe77/Lib/stdint.i#L20-L24,因此您可以使用SWIGWORDSIZE64但控制typedef ...

现在不好了:SWIG JavaSWIG CSHARP没有考虑到它

所以你可能想用

#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)

#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)

因此int64_t又名long intlong在Linux上绑定到Java / C#...


首先long longlong int是不同的类型,但是sizeof(long long) == sizeof(long int) == sizeof(int64_t) 哦?尝试使用-m32....
Andrew Henle

@AndrewHenle对不起,它隐式地针对k8架构主机开发,否则您将不会遇到32位的任何
麻烦
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.