0

I read that stdint.h is used for portability, but I'm confused.

If I wrote a program on a 32-bit system, uint32_t (unsigned int) is 4-bytes.

But when this program is run on 16-bit system, int is 2bytes and uint32_t (unsigned int) is 2bytes.

I think portability is not guaranteed in this case. Is there anything I am understanding wrong?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
porpomas
  • 41
  • 4

2 Answers2

6

Is there any thing I am understanding wrong?

Yes.

Type uint32_t is always an unsigned integer type with exactly 32 bits, none of them padding bits. On many modern systems that corresponds to type unsigned int, but on others it might correspond to a different type, such as unsigned long int. On systems that do not have a type with the correct properties, it is not defined at all.

The point of uint32_t and the other explicit-width data types from stdint.h is exactly to address the issue you raise, that (for example) unsigned int has a different size on different machines.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • I thought stdint.h just use typedef. But it seems use other mechanisms like cheking wordsize and include other header files. these thing make the bit size consistent, right? – porpomas Nov 15 '22 at 17:17
  • @porpomas, the language spec does not specify what mechanism a C implementation uses to define `uint32_t`, *etc*. A `typedef` is a likely possibility, but not the only one. But perhaps you are failing to recognize that different C implementations might provide different typedefs for `uint32_t` and other types. – John Bollinger Nov 15 '22 at 17:21
  • 2
    @porpomas yes, it mostly provides typedef. That does not mean you get the same definitions for every compiler. – Gerhardh Nov 15 '22 at 17:21
  • @porpomas: At the end of the day `stdint.h` indeed comes down to `typedef`s, however the particular exact definition of that will be determined at compile time by a combination of preprocessor `#if`s and target macros defined by the compiler itself. Also some compilers (for example GCC and Clang) will define macros with the appropriate type definitions. If using GCC or Clang look at it's output when calling it like this: `gcc -E -dM - < /dev/null | egrep '__.INT.*_TYPE'` – datenwolf Nov 15 '22 at 17:22
  • @porpomas: Now if you were to call it with a different compilation target, those type definition macros would be sufficiently changed for that particular target. – datenwolf Nov 15 '22 at 17:24
1

A uint32_t and a uint16_t are distinct types from int.

While the size of int may vary, a uint32_t is always 32 bit and a uint16_t is always 16 bit.

dbush
  • 205,898
  • 23
  • 218
  • 273