【问题标题】:Definition of int64_tint64_t 的定义
【发布时间】:2012-11-16 05:58:27
【问题描述】:

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

a) 你能解释一下int64_tlong (long int) 之间的区别吗? 据我了解,两者都是 64 位整数。有什么理由选择其中一个吗?

b) 我试图在网上查找int64_t 的定义,但没有成功。有没有我需要咨询这些问题的权威来源?

c) 对于使用int64_t 编译的代码,我目前包括<iostream>,这对我来说没有多大意义。是否还有其他包含声明 int64_t

【问题讨论】:

  • 在我的编译器上,sizeof(long) == 4
  • 在很多地方,long 不是 64 位的...您是否尝试过查找一些有关 in64_t 的文档,例如 cppreference.com 上的文档?
  • @DavidHefernan:那仍然可能是 64 位;)
  • 关于long,您只能说它不比int
  • cdarke,不仅如此,你还可以说它至少是32位

标签: c++ c integer long-integer


【解决方案1】:

我的 2 美分, 从当前实现的角度来看,对于 k8 (x86_64) 架构上的 SWIG 用户。

Linux

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

GCC

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

MacOS

在 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

SWIG 东西

首先查看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 aka long int 将在 Linux 上绑定到 Java/C# long...

【讨论】:

  • 第一个long longlong int 是不同的类型但是sizeof(long long) == sizeof(long int) == sizeof(int64_t) 哦?尝试使用-m32....进行编译。
  • @AndrewHenle 抱歉,它隐含地针对 k8 架构主机开发,否则你不会有任何 32 位的痛饮问题
【解决方案2】:

a) 你能解释一下int64_tlong (long int) 之间的区别吗?据我了解,两者都是 64 位整数。有什么理由选择其中一个吗?

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

b) 我试图在网上查找int64_t 的定义,但没有成功。有没有我需要咨询这些问题的权威来源?

http://cppreference.com 在这里介绍:http://en.cppreference.com/w/cpp/types/integer。然而,权威来源是C++ standard(这个特定的位可以在§18.4 整数类型[cstdint]中找到)。

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

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

【讨论】:

  • 对于标准的鉴赏家:int64_t 保证使用 2 的补码表示并且没有填充位,并且是可选的(尽管如果实现具有符合标准的标准类型,则它必须存在账单)。 long int 既不保证也总是要求存在。而当 C++11 标准在 18.4 中提到“C 标准”时,就是指 C99。
  • @SteveJessop 为什么有人会使用int64_t 而不是long int,反之亦然?
  • @Dave:在这两者之间,最常见影响决策的区别在于long int 可能只有 32 位。因此,如果您要存储大于 20 亿的数字,并且必须在这两者之间进行选择,那么显然选择 int64_t。反之亦然,这更棘手,因为long int 没有很多int64_t 缺乏的引人注目的保证属性。但是,它保证存在,int64_t 不存在。当您使用非便携式书写并且知道大小时,如果 long int 是您想要的大小,那么只需使用它并继续您的生活。
【解决方案3】:

int64_ttypedef 你可以在 C 中的 <stdint.h> 中找到它

【讨论】:

    【解决方案4】:

    int64_t 由 C99 标准保证在实现它的平台上恰好为 64 位宽,对于至少 32 位的 long 没有这样的保证,因此它可能是更多。

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

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-20
        • 2021-08-06
        • 2011-11-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多