Is there a reliable way to declare typedefs for integer types of fixed 8,16,32, and 64 bit length in ISO Standard C?
When I say ISO Standard C, I mean that strictly:
I see other questions similar to this in StackOverflow, but no answers yet that do not violate one of the above constraints. I'm not sure it's possible without resorting to platform symbols.
The fixed-width integer types that <inttypes. h> provides, include signed integer types, such as int8_t, int16_t, int32_t, int64_t, and unsigned integer types, such as uint8_t, uint16_t, uint32_t, and uint64_t.
uint32_t is a numeric type that guarantees 32 bits. The value is unsigned, meaning that the range of values goes from 0 to 232 - 1. This. uint32_t* ptr; declares a pointer of type uint32_t* , but the pointer is uninitialized, that is, the pointer does not point to anywhere in particular.
The typedef is a keyword used in C programming to provide some meaningful names to the already existing variable in the C program. It behaves similarly as we define the alias for the commands. In short, we can say that this keyword is used to redefine the name of an already existing variable.
It's defined in /usr/include/stdint.
Yes you can.
The header file limits.h
should be part of C90. Then I would test through preprocessor directives values of SHRT_MAX
, INT_MAX
, LONG_MAX
, and LLONG_MAX
and set typedefs accordingly.
Example:
#include <limits.h>
#if SHRT_MAX == 2147483647
typedef unsigned short int uint32_t;
#elif INT_MAX == 2147483647
typedef unsigned int uint32_t;
#elif LONG_MAX == 2147483647
typedef unsigned long uint32_t ;
#elif LLONG_MAX == 2147483647
typedef unsigned long long uint32_t;
#else
#error "Cannot find 32bit integer."
#endif
Strictly speaking, ISO 9899:1999 superceded ISO 9899:1990 so is the only current ISO standard C language specification.
As exact width typedef names for integer types were only introduced into the standard in the 1999 version, what you want is not possible using only the 1990 version of the standard.
There is none. There is a reliable way to declare individual integer variables up to 32 bits in size, however, if you're willing to live with some restrictions. Just use long
bitfields (the latter is guaranteed to be at least 32-bit wide, and you're allowed to use up to as many bits in a bitfields as would fit in the variable if bitfield declarator was omitted). So:
struct {
unsigned long foo : 32;
} bar;
Obviously, you get all the limitations that come with that, such as inability to have pointers to such variables. The only thing this really buys you is guaranteed wraparound at the specified boundary on over/underflow, and even then only for unsigned types, since overflow is undefined for signed.
Aside from that, there's no portable way to do this in pure C90. Among other things, a conformant C90 implementation need not even have a 8-bit integer, for example - it would be entirely legal to have a platform in which sizeof(char) == sizeof(short) == sizeof(int) == 1
and CHAR_BIT == 16
(i.e. it has a 16-bit machine word, and cannot address individual bytes). I've heard that such platforms do in fact exist in practice in form of some DSPs.
A danger with such approaches when using modern compilers is that it has become fashionable for compilers to assume that a pointer of one integer type will not be used to access values of another, even when both types have the same size and representation. If two types have the same size and representation, and two parts of the same program each choose one of them, applying link-time optimizations to programs that share pointers to such data could result in improper behavior. For some implementations on many systems, there will be at least one size of integer for which it will be impossible to declare a pointer which can be safely used to access all integer values of that size; e.g. on systems where both long
and long long
are 64 bits, there will be no way to declare a pointer which can be used reliably to access data of either type interchangeably.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With