Visual Studio stdint.h seems to have the following typedefs:
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;
However, sized integer types use the __intN
syntax, as described here: https://learn.microsoft.com/en-us/cpp/cpp/int8-int16-int32-int64?view=msvc-170
Is there any difference (for example) between using int32_t
versus using __int32
?
I guess I am a little confused if the purpose of the int32_t
typedef is to be the ANSI C99 standard to abstract away the specific compiler syntax (so you can use int32_t
in both Visual Studio and gcc C code for example), then I’m not sure why the typedef in Visual Studio wouldn’t be: typedef __int32 int32_t;
Say that the codebase has the following:
#ifdef _MSC_VER
typedef __int64 PROD_INT64;
#else
typedef int64_t PROD_INT64;
#endif
And it uses PROD_INT64
everywhere for a 64-bit signed integer, and it is compiled in both Visual Studio and gcc.
Can it simply use the int64_t
in both Visual Studio and gcc? It would seem this is changing __int64
for long long
in Visual Studio.
3
Answers
Q: Is there any difference (for example) between using int32_t versus using __int32?
A: Yes:
In other words, for any NEW code, you should use "int32_t".
Your wording suggests that you think the
__intN
syntax is somehow more correct or fundamental than all other alternatives. That’s not what the doc you link says. It simply defines what those particular forms mean. In Microsoft C, those are preferred over Microsoft’s older, single-underscore forms (_intN
), but there’s no particular reason to think that they are to be preferred over other alternatives, such as theintN_t
forms available when you includestdint.h
. The key distinguishing characteristic of the__intN
types is that they are built in, available without including any particular header.On Windows,
int32_t
is the same type as__int32
, but the former is standard C, whereas the latter is not.You need to include
stdint.h
to useint32_t
, whereas__int32
is built in to MSVC.It’s an implementation decision that may or may not have a well-considered reason. As long as the implementation provides correct definitions — and there’s no reason to think MSVC is doing otherwise — you shouldn’t care about the details.
Yes, and that’s certainly what I would do.
Which is a distinction without a difference. Both of those spellings give you the same type in MSVC.
From my top comments …
stdint.h
is provided by the compiler rather than libc or the OS. It provides portable guarantees (e.g.int32_t
will be 32 bits). The compiler designers could do:Or, they can do:
The latter is what most
stdint.h
files do (since they don’t have the__int*
types).Probably, the VS compiler designers just grabbed a copy of the standard stdint.h and didn’t bother to change it.
Your point is valid, it’s just a design choice (or lack of it) that the compiler writers made. Just use the standard/portable
int32_t
and don’t worry 😉Historical note:
stdint.h
is relatively recent. In the 1980s, MS had [16 bit] MS/DOS. Many mc68000 based micros at the time definedint
to be 32 bits. But, on the MS C compiler,int
was 16 bits because that fit the 8086 arch best.stdint.h
didn’t exist back then. But, if it did, it would need:because
long
was the only way to define a 32 bit integer for the MS 8086 compiler.When 64 bit machines became available, POSIX compliant machines allowed
long
to "float" with the arch/mode. It was 32 bits on 32 bit arches, and 64 bits on 64 arches. This is theLP64
memory model.Here’s the original rationale: https://unix.org/version2/whatsnew/lp64_wp.htm
But, because of MS’s longstanding use of
long
to be a 32 bit integer, it couldn’t do this. Too many programs written in the 8086 days would break if recompiled.IIRC [and I could be wrong]:
__int64
andLONGLONG
as types.near
andfar
pointers, anyone ;-)?]So, IMO, it was, in part, because of all the MS craziness that prompted the creation of
stdint.h
in the first place.