1

I'm somewhat familiar with the concept of stdint.h in C. By explicitly stating the size of the integer, the header file will replace the #define integer with the appropriate integer on that machine. For example, if my machine has 16 bit unsigned integers, uint32_t would be replaced with long unsigned int.

However, let say your machine only supports up to 32 bit integers. What would happen if you used an int64_t ? If this integer size is not natively supported, how would this be resolved since there is no substitution that can fix it?

Would the compiler throw and error saying that it can't be resolved? Or would it attempt to use two 32bit allocations to hold the 64bit data type?

Izzo
  • 4,461
  • 13
  • 45
  • 82
  • 1
    There are C compiler for 8-bit CPU (where registers are only 8-bit) without Math coprocessor. And they support `long` and `float` type. Can you imagine? – i486 Jan 12 '17 at 15:52

3 Answers3

5

If a certain stdint type isn't supported, the code won't compile. You can check if they are supported like this:

#include <stdint.h>

#ifndef UINT64_MAX
#error uint64_t not supported
#endif

If your compiler supports a type but your CPU does not, it means that some compiler library code will get silently invoked to emulate the larger type.

For example if you use uint32_t on a 8-bit microcontroller, compilers tend to support it, but since the type is only emulated through software, the resulting machine code will grow big and slow.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Curious, the `#ifndef UINT64_MAX` is certainly good, but what specification prevents other code from defining `UINT64_MAX` - aside form good coding practice. – chux - Reinstate Monica Jan 12 '17 at 16:21
  • Is UINT64_MAX defined by stdint.h or is it limits.h? – user253751 Jan 12 '17 at 20:12
  • @immibis stdint.h – Lundin Jan 13 '17 at 07:32
  • 1
    @chux The C standard 7.1.3 "Each macro name in any of the following subclauses (including the future library directions) is reserved for use as specified if any of its associated headers is included; unless explicitly stated otherwise" – Lundin Jan 13 '17 at 07:33
2

Computers (processors) do not limit the upper bit width of an integer type. The compiler imposes limits. The hardware does affect the complexity and efficiency of handling large integer types. Even a 1-bit platform can do 64-bit math given enough time and memory.

A compliant C compiler, C99 onward, supports integer widths at least up to 64 bit.

Yes, a 32-bit machine typically handles 64-bit operations using a pair of 32-bit internal objects.


To be clear. a C99 compiler needs to handle some integer type at least 64 bits to implement the required long long. A platform may or may be implement uint64_t, the 64-bit width, no padding, 2's complement integer type. It is very commonly implemented.

 unsigned long long ull; // must exist

 #include <stdint.h>
 uint_least64_t uleast64;  // must exist

 uint64_t u64; // may exist 
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • Compliant compilers does not have to support up to 64 bits if the machine for some reason can't handle them. 7.20.1.1 "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." For example, not many 8-bit MCU compilers support uint64_t. – Lundin Jan 12 '17 at 16:04
  • I understand that a processor could do any size integer arithmetic by breaking up instructions, however, let's say I'm just interested in read/writing from memory. If I were to attempt to declare a pointer to an int64_t in memory, and then decided to dereference that pointer, would it be able to dereference ok? Or will it only dereference the first 32bit integer? – Izzo Jan 12 '17 at 16:05
  • 1
    @Teague If your compiler supports `int64_t` then it will work as expected. It will read the data 32 bits at a time and then store the results according to endianess. But the read will be slow and never atomic. – Lundin Jan 12 '17 at 16:06
  • @Lundin My code appears to be tripping over the `int64_t` but still compiles... This will simply require more investigation from me. – Izzo Jan 12 '17 at 16:15
  • @Lundin "not many 8-bit MCU compilers support uint64_t." --> If such a compiler does not support `long long`, it is not a C99 compliant complier. Such a compiler need not follow `#ifndef UINT64_MAX` either in the hoped for fashion.. – chux - Reinstate Monica Jan 12 '17 at 16:23
1

The exact-width types declared in a particular C implementation's stdint.h (as typedefs, not macros) are all optional. Implementations are required to declare them only if they in fact provide a data type with the required characteristics.

In your particular example, if the C implementation in question does not offer a 64-bit, two's complement integer type with no padding bits, then its stdint.h will not declare type int64_t. If you then use that type without declaring it yourself, the compiler will reject your code.

Some others of the types provided by stdint.h are required; conforming implementations will definitely provide them. For the optional ones, you can test whether a compiler provides them by testing whether the corresponding macros for their limits are defined (e.g. INT64_MAX).

John Bollinger
  • 160,171
  • 8
  • 81
  • 157