4

How can you get a custom-sized integer data type? Is there any other answer than using <stdint.h> types like uint16_t and uint32_t and are these types platform-independent?

tomashauser
  • 561
  • 3
  • 16
  • 2
    ... are these types platform-independent? --> The existence of `uint16_t` and `uint32_t` _is_ platform-dependent. Although few machines today do not have 16-bit integers. Please provide an example of _custom-sized integer data type_ you would like. – chux - Reinstate Monica Dec 29 '19 at 23:14
  • `` is the way to get integer types of specified sizes. Why are you looking for a different solution? I'm not saying there's no good reason, but knowing what *your* reason is would make it easier to give you a useful answer. What problem are you trying to solve? (If you're just curious, that's fine, but please say so.) – Keith Thompson Dec 29 '19 at 23:20
  • @KeithThompson It's an exam question. I just want to answer it right. I could ask "Is there a way of creating 256 bit integer?" or somehting like that. – tomashauser Dec 29 '19 at 23:25

3 Answers3

5

The answer is mostly No. <stdint.h> provides integers of specific sizes available on a given platform, but there's no standard way to get, say, a 20-bit integer but you can specify arbitrary size smaller than those provided by <stdint.h> by using bitfields. The following provides a 20-bit unsigned int that works as you would expect it to, though the interface is a little clunky.

struct uint20_s {
   unsigned int val : 20;
};

Broadly speaking it is non-trivial to implement integer semantics for word-sizes larger than those supported by the underlying hardware. There is an entire class of libraries dedicated to working with arbitrary precision numerics.

nickelpro
  • 2,537
  • 1
  • 19
  • 25
  • Doesn't this count: `struct s { unsigned long twentybit:20; };` ? – Lxer Lx Dec 29 '19 at 23:35
  • @LxerLx I thought the overflow semantics for bitfields was different but consulting the standard it appears I'm wrong. So yes, that works as long as you want an arbitrary type _smaller_ than max word length – nickelpro Dec 29 '19 at 23:41
  • 1
    @LxerLx `struct s { unsigned twentybit:20; };` works when `unsigned` is, say, 32 bits. (`unsigned` might be 16-bit.) `unsigned long twentybit:20;` and `uint32_t val : 20;` rely on implementation-defined aspects. "A bit-field shall have a type that is a qualified or unqualified version of `_Bool`, `signed int`, `unsigned int` or some other implementation-defined type.", not necessarily "smaller than max word length". – chux - Reinstate Monica Dec 29 '19 at 23:53
  • 1
    There is a standard way now... on 4/21/2020 clang released `_ExtInt` which allows you to make things like 20-bit ints. https://stackoverflow.com/questions/61411865/how-do-you-use-clangs-new-custom-size-int-feature – xilpex Apr 25 '20 at 16:48
5

You can get a custom-width integer as a member in a structure by using a bit field, as in:

struct foo { int x : 13; } f;

The maximum width supported for a bit-field is depends on both the implementation and the base type (int above) used for it.

The widths of standard types such as uint16_t and uint32_t are of course not implementation-dependent, but whether they are provided by an implementation is.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • As an additional note to the answer above, I would like to point out that it is implementation-defined whether the bit-field (`x` in the `struct foo` above) is `signed` or `unsigned`, since a _plain_ `int` is used to define it. – Lxer Lx Dec 30 '19 at 00:32
3

A little late to the party but... There is a good solution! Clang has this new feature (released on 4/24/2020), which allows you to declare custom size integers. You have to use the _ExtInt keyword. An example:

_ExtInt(13) foo;

Look here for some more details.

xilpex
  • 3,097
  • 2
  • 14
  • 45