2

From my research, these were the only guarantees that I could find about these built-in integer data types:

  • char will not be smaller than 8 bits
  • short will not be smaller than 16 bits
  • short will not be smaller than char

In practice, according to my experience, short is always double the size of char, but it does not appear that this is a guarantee made by the C language specification. It seems that a scenario such as a 16 bit char and a 16 bit short could still be valid.

This is more of a curiosity question, I realize that if you really need exact widths for your integer data types, you're better off using the stdint.h header.

UPDATE 5/6/2021: I do not believe this question is a duplicate of What platforms have something other than 8-bit char?. I am not asking about the specific size of a char, but rather the ratio between a char and a short, regardless of the actual size of either one. At least for me, many of these answers have enlightened me in a way that the "duplicate" question has not. I hope this also helps others that stumble upon it.

Alex Riveron
  • 389
  • 1
  • 10

3 Answers3

4

As a few people have already pointed out, the specification makes no guarantees about the "bit widths" of built in types, it's left up to the implementation of the compiler for the given architecture how these are defined.

What's maybe more interesting is how this gets used in practice. In fact there are "current" architectures which have built-in sizes that don't follow the usual 1-2-4-8 conventions. A good example of this (and the one that I have a fair amount of personal experience with) is the Analog Devices SHARC.

From the Wikipedia page:

it knows nothing of 8-bit or 16-bit values since each address is used to point to a whole 32-bit word, not just an octet. It is thus neither little-endian nor big-endian, though a compiler may use either convention if it implements 64-bit data and/or some way to pack multiple 8-bit or 16-bit values into a single 32-bit word. Analog Devices chose to avoid the issue by using a 32-bit char in their C compiler.

A 32-bit character could definitely be called a "pathological" case, but it works just fine for the SHARC, which is widely used in professional and prosumer audio applications. See Universal Audio's Apollo as an example.

Jon Reeves
  • 2,426
  • 3
  • 14
  • Interresting. It must be pretty difficult to write low-level code for this processor - at least to begin with. – Support Ukraine May 06 '21 at 15:49
  • 1
    @4386427 But it is rather convenient on the other hand. No alignment issues, for example. – Eugene Sh. May 06 '21 at 15:52
  • @4386427 You do get used to it. To be fair though, the most common application for the SHARC is floating point signal processing so you tend not use `char` or `short` all that much anyway. If you find yourself doing a lot of string manipulation on a SHARC for example, you probably picked the wrong part for the job. – Jon Reeves May 06 '21 at 15:59
3

In theory, all of char, short, int could have the same size.

Very few implementations are doing that in practice (I cannot name any; I think in the previous century you might have found some)

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
3

There is no such guarantee.

The C standard specifies the following values as minimums:

#define CHAR_BIT                         8
#define CHAR_MAX    UCHAR_MAX or SCHAR_MAX
#define CHAR_MIN            0 or SCHAR_MIN
#define INT_MAX                     +32767
#define INT_MIN                     -32767
#define LONG_MAX               +2147483647
#define LONG_MIN               -2147483647
#define LLONG_MAX     +9223372036854775807
#define LLONG_MIN     -9223372036854775807
#define MB_LEN_MAX                       1
#define SCHAR_MAX                     +127
#define SCHAR_MIN                     -127
#define SHRT_MAX                    +32767
#define SHRT_MIN                    -32767
#define UCHAR_MAX                      255
#define USHRT_MAX                    65535
#define UINT_MAX                     65535
#define ULONG_MAX               4294967295
#define ULLONG_MAX    18446744073709551615

So you could have a system where CHAR_BIT is 16 and the max/min values for char match the above minimums for short and the ones for short are unchanged from above, in which case char and short would be the same size.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • I've found an [interesting article](https://gustedt.wordpress.com/2010/06/01/how-many-bits-has-a-byte) that claims that C99 de facto forces CHAR_BIT==8: – Ingo Leonhardt May 06 '21 at 15:32
  • 1
    @IngoLeonhardt The conclusion in that article can (at best) only be applied to posix compliant systems. And compliant C implementations do not need to be posix compliant. – Support Ukraine May 06 '21 at 15:39
  • @IngoLeonhardt Not really. It is claiming that POSIX is forcing it. – Eugene Sh. May 06 '21 at 15:39
  • you're both right. I've overlooked, that only POSIX requires `int8_t`. – Ingo Leonhardt May 06 '21 at 15:46
  • 3
    @IngoLeonhardt That article is wasting time going through those hoops to claim `CHAR_BIT` must be 8 is implied by POSIX. As an extension to the C standard, POSIX [already ***explicitly requires*** `CHAR_BIT` to be 8 in `limits.h`](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html#tag_13_24) (bolding mine): "{`CHAR_BIT`} Number of bits in a type char. **Value: 8**" It isn't "forced", it's ***required***. – Andrew Henle May 06 '21 at 16:06
  • @AndrewHenle that's funny. Thank you for the information – Ingo Leonhardt May 06 '21 at 16:08