It doesn't seem like the standard uses the word "type modifier". I think it's more useful to just think about the actual types (where the type names might be made up of those so called "type modifiers").
type name minimum size common size
signed char 8 bits 8 bits
unsigned char 8 bits 8 bits
char 8 bits 8 bits
(signed) short (int) 16 bits 16 bits
unsigned short (int) 16 bits 16 bits
(signed) (int) 16 bits 32 bits
unsigned (int) 16 bits 32 bits
(signed) long (int) 32 bits 32 or 64 bits
unsigned long (int) 32 bits 32 or 64 bits
(signed) long long (int) 64 bits 64 bits
unsigned long long (int) 64 bits 64 bits
|
The words in the type names that are written inside parentheses are optional and can be left out. For
signed int you can leave out either
signed or
int but you cannot leave out both for obvious reasons.
All the types listed above are separate types. Types listed on separate lines are always different types even if they happen to have the same size and signedness. Most notable is that
char, which is often signed but could be unsigned, is always a separate type from both
signed char and
unsigned char.
C++ tries to be very cross platform and support old, future and sometimes non-existent hardware by not specifying everything exactly. But that doesn't mean you cannot make more specific assumptions. If you're using a mainstream modern computer, and not some very specialized embedded device or old hardware, you can essentially rely on the "common sizes" listed above to be true.
A few notes:
- sizeof(char) is always 1 because that's how sizeof works. There's no type smaller than char. The size of all other types are an integer multiple of char. If char is 8 bits then you can't have types that are 12 bits. It has to be 8, 16, 24, 32, etc.
- The 8-bit byte is a very universal thing in modern computers. But C++ allow char to be larger, but that would mean there is no 8-bit type, which would make it incompatible with a lot of things. Dealing with byte formats (e.g. UTF-8) would be impossible, or at least very cumbersome. It's probably the main reason why the fixed-width integer types in <cstdint> are "optional". You might have been able to find these computers a long time ago but nowadays we use 8-bit bytes so the size of char will therefore be 8 bits in practice.
- On modern 32 and 64-bit computers the size of int is typically 32 bits. I don't think you will ever find it being smaller than that but I wouldn't rule out that it might be larger somewhere. On old 16-bit computers the size of int was 16 bits but those are not common today. That said, at least up to recently, it was extremely common in at least one big Asian country to use Turbo C++ (an ancient 16-bit compiler) with old DOS interface in their programming education for some reason but I'm not sure how likely you are to use something like that for anything serious nowadays.
- Integer types defined by the standard library (e.g. std::size_t, std::ptrdiff_t and types in <cstdint>) are usually typedefs of the types listed above. For example std::uint8_t is usually
unsigned char (but it doesn't have to be).