How to check if fixed width integers are defined
Asked Answered
C

2

29

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?

Curl answered 1/1, 2020 at 12:36 Comment(9)
There doesn't seem to be feature test macro, but I suppose you can do #if defined(INT8_MIN)Scanlan
If the std library does not provide a feature test macro for that, then you might check if the toolchain you use provides one for it or allows you to define an own test. CMake, for example, allows you to test for certain language features by compiling a defined cpp file and depending on if the compilation fails or not a macro that you can define is set.Frontogenesis
If you prefer autoconf to cmake, it has tests predefined for them. AC_TYPE_INT8_T etc.Beneath
If anyone has any tag score in stdint, IMO cstdint should be nominated as a synonym (stackoverflow.com/tags/stdint/synonyms). I don't think we need separate C and C++ tags for this obscure thing; the main tag on the question is enough.Dunson
@PeterCordes The top user in stdint has a score of 408. 40 makes it into the top 10. cstdint is even worse I'm at 9 with a score of - wait for it - 14. :-/ Only Lundin and R seem to have a high enough tag score so no way to get to 4 votes. (Just now saw your comment...)Handful
@AndrewHenle: I edited the tags on this to include both (because stdint seems more relevant than integer), so now you have some tag-score in stdint, too.Dunson
@PeterCordes Unfortunately, that didn't get me far enough.Handful
@AndrewHenle: try again; it might have taken until overnight for tag scores to recalc. It says you have 15, and creating synonyms only requires 5 in that tag (stdint).Dunson
@PeterCordes It worked this time: stackoverflow.com/tags/stdint/synonymsHandful
H
21

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 that typedef name and define the associated macros. Conversely, for each type described herein that the implementation does not provide, <stdint.h> shall not declare that typedef 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.

Handful answered 1/1, 2020 at 15:19 Comment(2)
It'll be shorter to check for [U]INT*_C instead of the min & max macrosCivic
@Civic Except that's not the same thing. e.g. INT64_C is defined if int64_least_t is available, not if int64_t is available. Refer to documentationEthnology
S
19

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.

Sheepshank answered 1/1, 2020 at 14:34 Comment(6)
This isn't true. I've written stub passthroughs that implement operator= / etc for platforms that don't support uint8_t before. But for efficiency and debugging purposes you don't want to use the passthrough unless its actually necessary.Wharfage
@TLW: "I've written stub passthroughs that implement operator= / etc for platforms that don't support uint8_t before." OK, but... why? What code were you writing which needs to be certain that a byte is 8 bits (which is presumably why you were using 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
proprietary so can't say too too much. Shared codebase that needed to support, among other things, a rather quirky hardware stack. uint8_t was much clearer than the prior ad-hoc (and oft-broken) approach.Wharfage
If you have an algorithm that is expressed in terms of e.g. 8-bit bytes, a passthrough is something that you can write once and is easy to test. Whereas fixing up every place is ad-hoc and easy to get subtly incorrect. 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
@TLW: "Same reason why people use e.g. uint16_t." That's not my reason for using 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
ping. stackoverflow.com/tags/stdint/synonyms needs votes to make cstdint a synonym; you're one of a few users with any tag score in it.Dunson

© 2022 - 2024 — McMap. All rights reserved.