2.1. Data Types

2.1.1. Scalar Data Types

The table below lists the size and range of each scalar type as supported in the c29clang compiler. Many of the minimum and maximum values for each range are available as standard macros in the C standard header file limits.h.

The storage and alignment of data types is described in Object Representation.

Type

Size

Min Value

Max Value

signed char

8 bits

-128

127

char, unsigned char, bool

8 bits

0

255

short, signed short

16 bits

-32768

32767

unsigned short

16 bits

0

65535

int, signed int, long, signed long

32 bits

-2147483648

2147483647

enum

packed

-2147483648

2147483647

unsigned int, unsigned long, wchar_t

32 bits

0

4294967295

long long, signed long long

64 bits

-9223372036854775808

9223372036854775807

unsigned long long

64 bits

0

18446744073709551615

float

32 bits

1.175494e-38

3.40282346e+38

double, long double

64 bits

2.22507385e-308

1.79769313e+308

pointers, references, data member ptrs

32 bits

0

0xFFFFFFFF

Notes:

  • The “plain” char type has the same representation as either signed char or unsigned char. The -fsigned-char and -funsigned-char options control whether “plain” char is signed or unsigned. The default is unsigned.

  • The wchar_t type has the same representation as unsigned int. The c29clang runtime libraries do not support a 16-bit wchar_t type. Attempts to use the c29clang -fshort-wchar option may cause issues when linked with the c29clang runtime libraries.

  • Further discussion about the size of enum types can be found below in the Enum Type Storage.

  • Specified minimum values for floating-point types in the table above indicate the smallest precision value > 0.

  • Negative values for signed types are represented using two’s complement.

  • 64-bit data types are aligned to 64-bit (8-byte) boundaries.

  • Both 32-bit pointers and 64-bit pointers are aligned to 32-bit (4-byte) boundaries.

  • Data and registers on C29x devices are always stored in little-endian format.

2.1.2. Enum Type Storage

The type of the storage container for an enumerated type is the smallest integer type that contains all the enumerated values. The container types for enumerators are shown in the following table:

Lower Bound Range

Upper Bound Range

Enumerator Type

0 to 255

0 to 255

unsigned char

-128 to 1

-128 to 127

signed char

0 to 65535

256 to 65535

unsigned short

-128 to 1, -32768 to -129

128 to 32767, -32768 to 32767

signed short

0 to 4294967295

2147483648 to 4294967295

unsigned int

-32768 to -1,

-2147483648 to -32769,

0 to 2147483647

32767 to 2147483647,

-2147483648 to 2147483647,

65536 to 2147483647

signed int

The compiler determines the type based on the range of the lowest and highest elements of the enumerator.

For example, the following code results in an enumerator type of int:

enum COLORS {
  green  = -200,
  blue   = 1,
  yellow = 2,
  red    = 60000
};

The following code results in an enumerator type of short:

enum COLORS {
  green  = -200,
  blue   = 1,
  yellow = 2,
  red    = 30000
};

2.1.3. Enum Type Size

An enum type is represented by an underlying integer type. The size of the integer type and whether it is signed is based on the range of values of the enumerated constants.

By default, the c29clang uses the smallest possible byte size for the enumeration type. The underlying type is the first type in the following list in which all the enumerated constant values can be represented: signed char, unsigned char, short, unsigned short, int, unsigned int, long, unsigned long, long long, unsigned long long. This default behavior is equivalent to the effect of using the c29clang -fshort-enums option.

In strict c89/c99/c11 mode, the compiler will limit enumeration constants to those values that fit in int or unsigned int.

For C++ and gnuXX C dialects (relaxed c89/c99/c11), the compiler allows enumeration constants up to the largest integral type (64 bits).

You can alter the default compiler behavior using the -fno-short-enums option. When the -fno-short-enums option is used in strict c89/c99/c11 mode, the enumeration type used to represent an enum will be int, even if the values of the enumeration constants fit into a smaller integer type.

When the fno-short-enums option is used with C++ or gnuXX C dialects, the underlying enumeration type will be the first type in the following list in which all the enumerated constant values can be represented: int, unsigned int, long, unsigned long, long long, unsigned long long.

The following enum uses 8 bits instead of 32 bits by default (since -fshort-enums option behavior is in effect):

enum example_enum {
  first  = -128,
  second = 0,
  third  = 127
};

The following enum fits into 16 bits instead of 32 by default:

enum a_short_enum {
  bottom = -32768,
  middle = 0,
  top    = 32767
};

Note

Do not link object files compiled with the -fno-short-enums option with object files that were compiled without it. If you use the -fno-short-enums option, you must use it with all of your C/C++ files; otherwise, you will encounter errors that cannot be detected until run time.