In C++, fixed width integers are defined as optional, but I can't seem to find the recommended way to check if they are actually defined.
What would be a portable way to check if fixed width integers are available?
In C++, fixed width integers are defined as optional, but I can't seem to find the recommended way to check if they are actually defined.
What would be a portable way to check if fixed width integers are available?
To determine if a fixed-width integer type is provided, you can check if either of the corresponding [U]INT*_MAX
or [U]INT*_MIN
macros is defined.
// may be necessary for your C++ implementation
#define __STDC_LIMIT_MACROS
#include <cstdint>
#ifdef INT32_MAX
// int32_t must be available to get here
int32_t some32bitIntVariable;
#endif
Per 7.20 Integer types <stdint.h>
, paragraph 4 of the C11 standard (note the bolded parts):
For each type described herein that the implementation provides,
<stdint.h>
shall declare thattypedef
name and define the associated macros. Conversely, for each type described herein that the implementation does not provide,<stdint.h>
shall not declare thattypedef
name nor shall it define the associated macros.
C++ inherits the C implementation via <cstdint>
. See <cstdint>
vs <stdint.h>
for some details. Also see What do __STDC_LIMIT_MACROS
and __STDC_CONSTANT_MACROS
mean? for details on __STDC_LIMIT_MACROS
.
Thus, if int32_t
is available, INT32_MAX
and INT32_MIN
must be #define
'd. Conversely, if int32_t
is not available, neither INT32_MAX
nor INT32_MIN
are allowed to be #define
'd.
Note though, as @NicolBolas stated in another answer, it may not be necessary to actually check.
[U]INT*_C
instead of the min & max macros –
Civic INT64_C
is defined if int64_least_t
is available, not if int64_t
is available. Refer to documentation –
Ethnology Broadly speaking... you don't.
If you need to use the fixed-sized integer types, then that means that you explicitly need those types to be of their specific sizes. That is, your code will be non-functional if you cannot get integers of those sizes. So you should just use them; if someone uses your code on a compiler that lacks said types, then your code will not compile. Which is fine, because your code wouldn't have worked if it did compile.
If you don't actually need fixed-sized integers but simply want them for some other reason, then use the int_least_*
types. If the implementation can give you exactly that size, then the least_*
types will have that size.
uint8_t
), but this code somehow needed to run on a platform where a byte isn't 8 bits (which, besides using an old C++ implementation, would be the only reason why uint8_t
wouldn't be available)? That is, outside of backwards compatibility, why did you need to do this? –
Sheepshank uint8_t
was much clearer than the prior ad-hoc (and oft-broken) approach. –
Wharfage O(1)
versus O(n)
effort. Same reason why people use e.g. uint16_t
. You're asking "why not use uint32_t and cast it yourself?", to which the answer should be obvious. –
Wharfage uint16_t
. My reason is that I'm communicating with a device/format/etc that is expecting to get precisely 16 bits of data formatted as a binary, unsigned integer using the endian for my machine, and if I can't get a type that is precisely that, then communicating effectively with it is much more difficult. My program (and the APIs that I use with it) fundamentally cannot function on a machine that doesn't provide that. –
Sheepshank © 2022 - 2024 — McMap. All rights reserved.
#if defined(INT8_MIN)
– Scanlancpp
file and depending on if the compilation fails or not a macro that you can define is set. – FrontogenesisAC_TYPE_INT8_T
etc. – Beneath