2

Does the C99 standard mandate that a conforming compiler have a 64-bit int64_t defined (and usable)? Or is it optional, and just happens to be defined by all popular compilers? I'm obviously asking specifically about platforms on which the CPU can't process 64-bit values directly, but the question is more general

I can't really figure this out from the C data types Wikipedia page, nor from this answer to a related question.

alk
  • 69,737
  • 10
  • 105
  • 255
einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • Not sure about C99, but `int64_t` is definitely optional in C11, except when it's not. See section 7.20.1.1 of the C11 specification for details. – user3386109 Feb 27 '19 at 22:57
  • @user3386109: Could I trouble you for a link? Also, your phrasing is rather cryptic. – einpoklum Feb 27 '19 at 22:59
  • Sorry, I don't have a link. But the draft of the C11 specification is freely available online, and can be found by searching for `N1570` – user3386109 Feb 27 '19 at 23:01
  • [Link to C11 draft](https://port70.net/~nsz/c/c11/n1570.html#7.20.1.1p3). The types are optional but should be provided if the machine architecture has an appropriate type, and must be provided if some integer type has the same characteristics. – rici Feb 27 '19 at 23:03
  • 1
    Anyway, the answer is "no". You cannot count on the types existing. – rici Feb 27 '19 at 23:08
  • Possible duplicate of [Understanding fixed width integer types](https://stackoverflow.com/questions/51173366/understanding-fixed-width-integer-types) – phuclv Feb 28 '19 at 16:25
  • [Are there any platforms where fixed width types (intXX_t) are missing?](https://stackoverflow.com/q/51590607/995714), [Can stdint's int8_t exist on an architecture that does not have 8-bit bytes?](https://stackoverflow.com/q/15336136/995714), [Understanding fixed width integer types](https://stackoverflow.com/q/51173366/995714), [How to check if uint8_t exists as a type, instead of unsigned char?](https://stackoverflow.com/q/18131032/995714), [Are the fixed width integer types guaranteed to be typedefs for the standard built in types?](https://stackoverflow.com/q/31037764/995714) – phuclv Feb 28 '19 at 16:40
  • @phuclv: All of that stuff is simply not what I asked. – einpoklum Mar 01 '19 at 00:23
  • definitely yes. They all say that fixed-width integers are not required on systems that can't support them. Only the `least` variant is required – phuclv Mar 01 '19 at 01:34

4 Answers4

5

Does the C99 standard mandate that a conforming compiler have a 64-bit int64_t defined (and usable)? Or is it optional, and just happens to be defined by all popular compilers?

The type is optional, in one sense, and conditionally required in a different sense. Specifically, C99 says,

The typedef name intN_t designates a signed integer type with width N , no padding bits, and a two's complement representation. [...]

These types are optional. However, if an implementation provides integer types with widths of 8, 16, 32, or 64 bits, no padding bits, and (for the signed types) that have a two's complement representation, it shall define the corresponding typedef names.

Thus, int64_t is optional in the sense that a conforming implementation is not required to provide any type that exactly matches the characteristics of an int64_t, and if it doesn't, then it needn't (indeed, must not, according to another section) provide type int64_t.

C99 does specify that there is a type long long int whose required minimum range necessitates a representation at least 64 bits wide. Now it is possible that in some implementation there is no signed integer type exactly 64 bits wide (for example, maybe int is 24 bits, long 48, and long long 96), and it is possible that there is a 64-value-bit integer type, but it contains padding bits or is not represented in two's complement. Such implementations could be fully conforming and yet not define an int64_t. In practice, though, there aren't any such implementations in common use today.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • So can you have a C99-conforming compiler which does not provide `int64_t`? I mean, can, say `long long` have a non-power-of-2 size, or 128 bits, and `int64_t` be missing? – einpoklum Feb 28 '19 at 08:33
  • Yes, @einpoklum, in principle you can. As I said, "a conforming implementation is not required to provide any type that exactly matches the characteristics of an int64_t, and if it doesn't, then it needn't (indeed, must not [...]) provide type int64_t". However, in practice, I am not aware of any existing, conforming C99 or C11 implementation that fails to provide `int64_t`. – John Bollinger Feb 28 '19 at 14:13
2

Does the C99 standard mandate that a conforming compiler have a 64-bit int64_t defined (and usable)?

No, yet C99 requires long long which is at least 64-bits.

Further, int64_t is very commonly available. It would be very unlikely you will encounter a conformant C99 without int64_t as it is required on nearly all platforms.

C11dr 7.20.1.1 Exact-width integer types
(int64_t) .... if an implementation provides integer types with widths of 8, 16, 32, or 64 bits, no padding bits, and (for the signed types) that have a two’s complement representation, it shall define the corresponding typedef names.

The bit width of the processor is not a factor in this functionality - long long must exist. If that long long (or any standard type is 64-bit 2's compliment), then int64_t must exist too. A processer's bit width does affect performance.


@R.. comment emphasizes that a long long that takes 64-bits of memory to encode, can, by spec only support the range of [-0x7fff-ffff-ffff-ffff ... +0x7fff-ffff-ffff-ffff], one shy of int64_t range of [-0x8000-0000-0000-0000 ... +0x7fff-ffff-ffff-ffff]. Such platforms these days are exceedingly rare, if they exist.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • C does not require `long long` to be 64-bit. `LLONG_MIN` is permitted to be `-0x7fffffffffffffff`, which makes it almost 100 zeptobits short of 64-bit if the implementation makes such a bad choice (and, for practical purposes, 63-bit). – R.. GitHub STOP HELPING ICE Feb 27 '19 at 23:24
  • @R.. Agree "C does not require `long long` to be 64-bit.", that is why the answer has "`long long` which is at _least_ 64-bits.". It could be wider. It could have a range as narrow as [-0x7fff-ffff-ffff-ffff ... +0x7fff-ffff-ffff-ffff] – chux - Reinstate Monica Feb 27 '19 at 23:32
  • It doesn't even require it to be "at least 64 bits". it requires it to be at least 63.999999999999999999921... bits. Sorry my first comment was misworded and missing the phrase "at least", but the point was that the "at least" is false due to the backwards provisions for allowing ones-complement, sign/magnitude, and "deficient twos complement" implementations. – R.. GitHub STOP HELPING ICE Feb 27 '19 at 23:33
  • @R.. Since there's no such thing as fractional bits, that's the same thing as "at least 64 bits". – Barmar Feb 27 '19 at 23:35
  • @Barmar: No, you have to round down if you only want to count whole bits, in which case it's effectively 63-bit (i.e. the largest power-of-two interval that's fully representable in the range is 2^63 in length, not 2^64). One way of thinking of this is that one bit is potentially "not fully usable". – R.. GitHub STOP HELPING ICE Feb 27 '19 at 23:36
  • @R.. Signed types are limited to the common _two’s complement_. The rare _sign and magnitude_ and _ones’ complement_ optional encoding require a minimal 64-bit encoding as well. Of course, we are splitting hairs/bits. ;-) – chux - Reinstate Monica Feb 27 '19 at 23:37
  • Note that the next version of the C standard will fix this, mandating full-range twos complement for all integer types. We have SO's own JF Bastien to thank for this! :-) – R.. GitHub STOP HELPING ICE Feb 27 '19 at 23:38
  • @R.. If you require at least 63.9999... bits, and you round down, you'll have less than that many bits and won't be able to encode the full range. – Barmar Feb 27 '19 at 23:39
  • @R.. Interesting news about next version of the C. Have an anticipated year? – chux - Reinstate Monica Feb 27 '19 at 23:39
  • I think it will be more focused on very important issues like trigraphs and so on. Any modernisation attempt will be opposed by IBM (as always) as they have created 60 years ago weird architectures and they want C standard to be implementable on it – 0___________ Feb 27 '19 at 23:40
  • @Barmar: The point is that you cannot represent a full 64-bit range on such an implementation, so if you want to treat `long long` as having power-of-two range, you have to treat it as only being 63-bit. Of course you can treat it as having the full almost-64-bit range, but that's not a 64-bit range and it's incorrect to describe it as such. – R.. GitHub STOP HELPING ICE Feb 27 '19 at 23:40
  • @chux: I think I saw an estimate somewhere but I don't recall where. I've been in contact with jfbastien on and off via Twitter and other channels regarding the proposal and its acceptance, though. – R.. GitHub STOP HELPING ICE Feb 27 '19 at 23:42
  • 1
    @R.. My point is how many bits you need to represent the required range. A sign/magnitude representation can't represent the same range as 64-bit two's complement, but it still needs 64 bits to represent that range (63 bits of magnitude, 1 bit of sign). – Barmar Feb 27 '19 at 23:44
  • @Barmar: Generally when using a type you care about the range of values it can represent, not (or at least more than) the amount of storage it requires. If you're talking about storage you'd also count padding bits. – R.. GitHub STOP HELPING ICE Feb 27 '19 at 23:47
  • @R.. Of course. But you were the one who said "it requires it to be at least 63.999999999999999999921... bits", which seems to be talking about the amount of storage. – Barmar Feb 27 '19 at 23:49
  • @Barmar: Rather it's talking about a space of possible values. Fractional bits make sense when talking about entropy/possibilities. – R.. GitHub STOP HELPING ICE Feb 28 '19 at 00:19
2

There are three sets of integer types:

  • intN_t — such as int64_t and their unsigned counterparts; these exact types may not be available.
  • int_leastN_t — such as int_least64_t; types int_least8_t, int_least16_t, int_least32_t and int_least64_t and their unsigned counterparts are required — other types are optional.
  • int_fastN_t — such as int_fast64_t; types int_fast8_t, int_fast16_t, int_fast32_t and int_fast64_t are required (they're the fastest type with at least the given width).

The standard also requires support for long long, and the minimum acceptable range for long long requires at least 64 bits (see §5.2.4.1 Sizes of integer types <limits.h>). Therefore, the standard can legitimately demand support for the 'least' and 'fast' types at 64 bits or more — it also requires that to support long long.

There used to be computers with 36-bit words, and others with 60-bit words. Both of these would struggle to provide (basically, "couldn't provide") the exact width types, but can easily provide support for the 'least' and 'fast' types.

The standard does not mandate the 'exact width types' — see §7.20.1.1 Exact-width integer types ¶3:

These types are optional. However, if an implementation provides integer types with widths of 8, 16, 32, or 64 bits, no padding bits, and (for the signed types) that have a two's complement representation, it shall define the corresponding typedef names.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • `There used to be computers with 36-bit words, and others with 60-bit words.` New standard should forget 40-50 years old computers. And yes there will not be conforming C21 compilers for them. Some standard fanatics would have a heart attack - there will be no way of writing portable code for the ferrite memory machines. End of the world. The life will be senseless. – 0___________ Feb 27 '19 at 23:31
  • 2
    What was faintly relevant twenty years ago is not so relevant now. In 1999, there were at least some machines of those types still running outside of computer museums. These days, not so much. – Jonathan Leffler Feb 27 '19 at 23:35
  • 1
    Also, there are DSP-class machines with `CHAR_BIT` of 16. They have problems with `int8_t`, but not the other types. – Jonathan Leffler Feb 27 '19 at 23:41
  • 1
    Note that while `int_least64_t` is mandated to exist, it need not have range at least as large as `int64_t` would if it existed. `int_least64_t` is permitted to only go down to -2^63+1 rather than all the way down to -2^63. This will be fixed in the next edition of the C standard. See *7.20.2.2 Limits of minimum-width integer types*. – R.. GitHub STOP HELPING ICE Feb 27 '19 at 23:43
  • @JonathanLeffler no one writes portable code for them. If someone tries to use uint8_t on them, should find an easier job – 0___________ Feb 27 '19 at 23:53
1

No, C99 does not mandate an int64_t type.

(Thanks @user3386109, @Clifford)

An int64_t type is not required to be available. Quoting the C99 standard draft document N1256:

7.18.11.1 Exact-width integer types

  1. The typedef name int N_t designates a signed integer type etc. etc. ...
  2. These types are optional. However, if an implementation provides integer types with widths of ... 64 bits... that have a two’s complement representation... it shall define the corresponding typedef name.

But see @chux and @JohnBollinger's answers about long long having 64 bits.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
einpoklum
  • 118,144
  • 57
  • 340
  • 684