https://jameshfisher.com/2017/01/23/c-type-of-constants/#:~:text=The%20C%20Programming%20Language%20says%3A%20An%20integer%20constant,the%20suffix%20ul%20or%20UL%20indicates%20unsigned%20long.
When we write expressions like this in C:
bool b = 1234567890 > 09876;
What are the types of those constants? The number 1234567890
- what is its type? How does C represent it when compiling it? The C Programming Language says:
An integer constant like
1234
is anint
. Along
constant is written with a terminall
(ell) orL
, as in123456789L
; an integer constant too big to fit into anint
will also be taken as along
. Unsigned constants are written with a terminalu
orU
, and the suffixul
orUL
indicatesunsigned long
.
Floating-point constants contain a decimal point (
123.4
) or an exponent (1e-2
) or both; their type isdouble
, unless suffixed. The suffixesf
orF
indicate afloat
constant;l
orL
indicate along double
.
Here are some examples:
0 // int
0l // long
1234 // int
1234L // long
0ul // unsigned long
0u // unsigned int
2147483647 // int (just)
2147483648 // long
2147483647u // unsigned int
2147483648u // unsigned long (but could have fitted into an unsigned int)
0x0101010101010101ULL // unsigned long long
Basic types
Here's a table containing commonly used types in C programming for quick access.
Type | Size (bytes) | Format Specifier |
---|---|---|
int |
at least 2, usually 4 | %d , %i |
char |
1 | %c |
float |
4 | %f |
double |
8 | %lf |
short int |
2 usually | %hd |
unsigned int |
at least 2, usually 4 | %u |
long int |
at least 4, usually 8 | %ld , %li |
long long int |
at least 8 | %lld , %lli |
unsigned long int |
at least 4 | %lu |
unsigned long long int |
at least 8 | %llu |
signed char |
1 | %c |
unsigned char |
1 | %c |
long double |
at least 10, usually 12 or 16 | %Lf |
1 << 31 and related issues
There are a few cases in FreeBSD where the expression (1 << 31) is used.
However this produces undefined behavior as '1' is of type int. (see
6.4.4p5: The type of an unmarked integer constant is the first of the
following list in which its value can be represented: int, long int,
long long int). The shift of 31 is illegal (see 6.5.7p4) if the size
of an int is 32. The same issue arises with 2 << 30 and 3 << 30.
I have been working on fixing this issue in a few different projects.
The correct fix here is to use 1U as the literal instead. adrian@ has
advocated for the macros BIT32(bit) and BIT64(bit) which I would also
support.