4.3.7.1 Integral Constants

The format of integral constants specifies their radix. MPLAB XC8 supports the standard radix specifiers, as well as ones which enables binary constants to be specified in C code.

The formats used to specify the radices are tabulated below. The letters used to specify binary or hexadecimal radices are case insensitive, as are the letters used to specify the hexadecimal digits.

Table 4-5. Radix Formats
Radix Format Example
binary 0bnumber or 0Bnumber 0b10011010
octal 0number 0763
decimal number 129
hexadecimal 0xnumber or 0Xnumber 0x2F

Any integral constant will have a type of int, long int or long long int, so that the type can hold the value without overflow. Constants specified in octal or hexadecimal can also be assigned a type of unsigned int, unsigned long int or unsigned long long int if their signed counterparts are too small to hold the value.

The default types of constants can be changed by the addition of a suffix after the digits; e.g., 23U, where U is the suffix. The table below shows the possible combination of suffixes and the types that are considered when assigning a type. For example, if the suffix l is specified and the value is a decimal constant, the compiler will assign the type long int, if that type will hold the constant; otherwise, it will assigned long long int. If the constant was specified as an octal or hexadecimal constant, then unsigned types are also considered.

Table 4-6. Suffixes And Assigned Types
Suffix Decimal Octal or Hexadecimal
u or U unsigned int

unsigned long int

unsigned long long int

unsigned int

unsigned long int

unsigned long long int

l or L long int

long long int

long int

unsigned long int

long long int

unsigned long long int

u or U, and l or L unsigned long int

unsigned long long int

unsigned long int

unsigned long long int

ll or LL long long int long long int

unsigned long long int

u or U, and ll or LL unsigned long long int unsigned long long int
Here is an example of code that can fail because the default type assigned to a constant is not appropriate:
unsigned long int result;
unsigned char shifter;
shifter = 20;
result = 1 << shifter;   // oops!

The constant 1 (one) will be assigned an int type, hence the result of the shift operation will be an int. Even though this result is assigned to the long variable, result, the result of the shift can never become larger than the size of an int, regardless of how much the constant is shifted. In this case, the value 1 shifted left 20 bits will yield the result 0, not 0x100000.

The following uses a suffix to change the type of the constant, hence ensure the shift result has an unsigned long type.
result = 1UL << shifter;