Definition von int64_t

74

Ich bin neu in C / C ++, daher habe ich einige Fragen zu einem Basistyp:

a) Können Sie mir den Unterschied zwischen int64_tund long( long int) erklären ? Nach meinem Verständnis sind beide 64-Bit-Ganzzahlen. Gibt es einen Grund, einen über den anderen zu wählen?

b) Ich habe versucht, die Definition von int64_tim Web nachzuschlagen, ohne großen Erfolg. Gibt es eine maßgebliche Quelle, die ich für solche Fragen konsultieren muss?

c) Für die Verwendung int64_tvon Code zum Kompilieren schließe ich derzeit ein <iostream>, was für mich wenig sinnvoll ist. Gibt es andere Includes, die eine Erklärung von abgeben int64_t?

clstaudt
quelle
4
Auf meinem Compilersizeof(long) == 4
David Heffernan
Es gibt viele Orte, an denen Longs nicht 64-Bit sind ... und haben Sie versucht, eine Dokumentation über in64_t wie die auf cppreference.com nachzuschlagen?
PlasmaHH
3
@ DavidHefernan: Das könnten noch 64 Bit sein;)
PlasmaHH
Alles, was Sie über a sagen können, longist, dass es nicht kürzer als ein ist int.
Cdarke
Cdarke, nicht nur das, man kann auch sagen, dass es mindestens 32 Bit ist
sasha.sochka

Antworten:

91

a) Können Sie mir den Unterschied zwischen int64_tund long( long int) erklären ? Nach meinem Verständnis sind beide 64-Bit-Ganzzahlen. Gibt es einen Grund, einen über den anderen zu wählen?

Ersteres ist ein vorzeichenbehafteter Integer-Typ mit genau 64 Bit. Letzteres ist ein vorzeichenbehafteter Integer-Typ mit mindestens 32 Bit.

b) Ich habe versucht, die Definition von int64_tim Web nachzuschlagen, ohne großen Erfolg. Gibt es eine maßgebliche Quelle, die ich für solche Fragen konsultieren muss?

http://cppreference.com behandelt dies hier: http://en.cppreference.com/w/cpp/types/integer . Die maßgebliche Quelle ist jedoch der C ++ - Standard (dieses spezielle Bit finden Sie in §18.4 Integer-Typen [cstdint]).

c) Für die Verwendung int64_tvon Code zum Kompilieren schließe ich ein <iostream>, was für mich nicht viel Sinn macht. Gibt es andere Includes, die eine Erklärung von abgeben int64_t?

Es wird in <cstdint>oder <cinttypes>(unter Namespace std) oder in <stdint.h>oder <inttypes.h>(im globalen Namespace) deklariert .

R. Martinho Fernandes
quelle
2
Und für Kenner des Standards: Es int64_twird garantiert, dass die Komplementdarstellung von 2 verwendet wird und keine Füllbits vorhanden sind. Dies ist optional (obwohl dies erforderlich ist, wenn die Implementierung einen Standardtyp hat, der der Rechnung entspricht). long intgarantiert beides nicht und muss immer existieren. Und wenn der C ++ 11-Standard in 18.4 auf "den C-Standard" verweist, bedeutet dies C99.
Steve Jessop
1
@SteveJessop Warum sollte jemand Gebrauch int64_tüber long intund umgekehrt?
Greg
@ Dave: Zwischen diesen beiden besteht der Unterschied, der die Entscheidung am häufigsten beeinflusst, darin, dass long intmöglicherweise nur 32 Bit vorhanden sind. Wenn Sie also Zahlen speichern möchten, die größer als 2 Milliarden sind, und zwischen diesen beiden wählen müssen, dann wählen Sie natürlich int64_t. Umgekehrt ist es schwieriger, weil long intes nicht sehr viele überzeugende garantierte Eigenschaften gibt, die int64_tfehlen. Es ist jedoch garantiert zu existieren, was int64_tnicht der Fall ist. Und wenn Sie nicht portabel schreiben und die Größen kennen, wenn long intSie die gewünschte Größe haben, verwenden Sie sie einfach und fahren Sie mit Ihrem Leben fort.
Steve Jessop
11

int64_twird durch den C99-Standard garantiert, dass er auf Plattformen, auf denen er implementiert ist, genau 64 Bit breit ist. Es gibt keine solche Garantie für einen, longder mindestens 32 Bit beträgt, also könnte es mehr sein.

§7.18.1.3 Ganzzahlentypen mit exakter Breite 1 Der Typedef-Name intN_t bezeichnet einen vorzeichenbehafteten Ganzzahltyp mit der Breite N, keinen Füllbits und einer Zweierkomplementdarstellung. Int8_t bezeichnet also einen vorzeichenbehafteten Integer-Typ mit einer Breite von genau 8 Bit.

iabdalkader
quelle
5

int64_tist typedef, dass Sie das <stdint.h>in C finden können

Omkant
quelle
3

Ein int64_t sollte auf jeder Plattform 64 Bit breit sein (daher der Name), während ein Long auf verschiedenen Plattformen unterschiedliche Längen haben kann. Insbesondere ist sizeof (long) oft 4, dh. 32 Bit.

Kylotan
quelle
1

Meine 2 Cent aus Sicht der aktuellen Implementierung und für SWIG-Benutzer auf k8 (x86_64) -Architektur.

Linux

Erstens long longund long intsind verschiedene Typen abersizeof(long long) == sizeof(long int) == sizeof(int64_t)

Gcc

Versuchen Sie zunächst herauszufinden, wo und wie der Compiler int64_t und uint64_t definiert

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;

Wir müssen also diese Compiler-Makrodefinition finden

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-Compiler:
-dMGibt eine Liste von Makros aus.
-Edruckt die Ergebnisse anstelle einer Datei nach stdout.
-x cund -x c++wählen Sie die Programmiersprache aus, wenn Sie eine Datei ohne Dateinamenerweiterung verwenden, z/dev/null

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

Hinweis: Für Swig-Benutzer unter Linux x86_64 verwenden -DSWIGWORDSIZE64

Mac OS

Auf 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:
-dMGibt eine Liste von Makros aus.
-Edruckt die Ergebnisse anstelle einer Datei nach stdout.
-x cund -x c++wählen Sie die Programmiersprache aus, wenn Sie eine Datei ohne Dateinamenerweiterung verwenden, z/dev/null

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

Hinweis: Für Swig-Benutzer wird unter macOS x86_64 nicht verwendet-DSWIGWORDSIZE64

Visual Studio 2019

Zuerst sizeof(long int) == 4undsizeof(long long) == 8

in haben stdint.hwir:

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

Hinweis: Für Swig-Benutzer unter Windows x86_64 nicht verwenden-DSWIGWORDSIZE64

SWIG Stuff

Siehe zuerst https://github.com/swig/swig/blob/3a329566f8ae6210a610012ecd60f6455229fe77/Lib/stdint.i#L20-L24, damit Sie das typedef steuern können, indem Sie SWIGWORDSIZE64...

jetzt das schlechte: SWIG Java und SWIG CSHARP berücksichtigen es nicht

Vielleicht möchten Sie also verwenden

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

und

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

Also wird int64_taka long intunter Java an Java / C # longgebunden ...

Mizux
quelle
Erstens long longund long intsind verschiedene Typen, abersizeof(long long) == sizeof(long int) == sizeof(int64_t) Oh? Versuchen Sie es mit -m32...
Andrew Henle
@AndrewHenle Entschuldigung, es war implizit auf die Entwicklung von Hosts mit k8-Architektur ausgerichtet, andernfalls gibt es für 32
Bit