From C11 5.2.4.2.1

The values given below shall be replaced by constant expressions suitable for use in #if preprocessing directives. Moreover, except for CHAR_BIT and MB_LEN_MAX, the following shall be replaced by expressions that have the same type as would an expression that is an object of the corresponding type converted according to the integer promotions. Their implementation-defined values shall be equal or greater in magnitude (absolute value) to those shown, with the same sign.

(emphasis mine)

So the standard defines that at a minimum UCHAR_MAX needs to be 255 but it can be greater than that.

The guarantees that we have on size are:

sizeof(char) = 1 and sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)

And at a minimum the signed versions of the data types must be able to hold:

  • char [-127, 127]
  • short [-32767, 32767]
  • int [-32767, 32767]
  • long [-2147483647, 2147483647]
  • long long [-9223372036854775807, 9223372036854775807]
Answer from NathanOliver on Stack Overflow
🌐
Microsoft Learn
learn.microsoft.com › en-us › cpp › cpp › data-type-ranges
Data Type Ranges | Microsoft Learn
- int (unsigned int) - __int8 (unsigned __int8) - __int16 (unsigned __int16) - __int32 (unsigned __int32) - __int64 (unsigned __int64) - short (unsigned short) - long (unsigned long) - long long (unsigned long long) If its name begins with two underscores (__), the data type is nonstandard. The ranges specified in the following table are inclusive-inclusive. A variable of __wchar_t designates either a wide-character type or multibyte-character type.
Discussions

What is the use of unsigned char?
There are 3 character types: signed char unsigned char char (yes, this is indeed a distinct type, not "alias", but for practical purposes it is the same as one of the above two, implementation specified) sizeof for these is defined to be 1. Using sizeof char is always redundant, though it can be used like a comment, making code more clear. On any platform you are likely to ever work on, char is 8 bits, and synonym to "byte". Therefore, int8_t is probably signed char and uint8_t is unsigned char typedefs. More on reddit.com
🌐 r/cpp_questions
39
9
April 20, 2023
c++ - How do you determine the length of an unsigned char*? - Stack Overflow
If you're using C++, and its a string in an unsigned char*, you're better off first putting it into a std::string before manipulating it. That way you can do all kinds of things to it and still be able to get the length() and/or capacity() of it whenever you want. I'm assuming that you're doing things to said array to make its size ... More on stackoverflow.com
🌐 stackoverflow.com
Difference between char, signed char, unsigned char, uint8_t, int8_t and std::byte?

Not all platforms implement char as 8 bits, the standard dictates that a char must be at least 8 bits, but doesn't require it to be.

int8_t was therefore added in order to avoid confusion, it's guaranteed to be exactly 8 bits but a platform specific compiler isn't required to implement it.

unsigned char and uint8_t respectively are the unsigned equivalent types.

std::byte follows the same rules as char, only it doesn't offer integer-specific arithmetics like +, - etc. This is in order to emphasize its intend as a binary data holder and not an alphanumeric value.

More on reddit.com
🌐 r/cpp_questions
14
5
October 13, 2021
Get sizeof(unsigned char *) - C++ Forum
I know that writing to a socket is done with `write(sfd, buf, buf_len)`. The first function converts a string to an unsigned char *. The second function will be usaed to send the unsigned car to the socket but now it should only display the size of the char array More on cplusplus.com
🌐 cplusplus.com
April 13, 2022

From C11 5.2.4.2.1

The values given below shall be replaced by constant expressions suitable for use in #if preprocessing directives. Moreover, except for CHAR_BIT and MB_LEN_MAX, the following shall be replaced by expressions that have the same type as would an expression that is an object of the corresponding type converted according to the integer promotions. Their implementation-defined values shall be equal or greater in magnitude (absolute value) to those shown, with the same sign.

(emphasis mine)

So the standard defines that at a minimum UCHAR_MAX needs to be 255 but it can be greater than that.

The guarantees that we have on size are:

sizeof(char) = 1 and sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)

And at a minimum the signed versions of the data types must be able to hold:

  • char [-127, 127]
  • short [-32767, 32767]
  • int [-32767, 32767]
  • long [-2147483647, 2147483647]
  • long long [-9223372036854775807, 9223372036854775807]
Answer from NathanOliver on Stack Overflow
🌐
Wikipedia
en.wikipedia.org › wiki › C_data_types
C data types - Wikipedia
2 weeks ago - In practice, char is usually 8 bits in size and short is usually 16 bits in size (as are their unsigned counterparts). This holds true for platforms as diverse as 1990s SunOS 4 Unix, Microsoft MS-DOS, modern Linux, and Microchip MCC18 for embedded 8-bit PIC microcontrollers.
🌐
GeeksforGeeks
geeksforgeeks.org › c language › unsigned-char-in-c-with-examples
unsigned char in C with Examples - GeeksforGeeks
July 12, 2025 - So it means that the range of unsigned char data type ranges from 0 to 255.
Find elsewhere
🌐
Arduino
docs.arduino.cc › language-reference › en › variables › data-types › unsignedChar
unsigned char
November 20, 2024 - Arduino programming language can be divided in three main parts: functions, values (variables and constants), and structure · For controlling the Arduino board and performing computations
🌐
IceCube
user-web.icecube.wisc.edu › ~dglo › c_class › fundamental_types.html
C Class - Fundamental Datatypes
CHAR_BIT 8 /* number of bits in a 'char' */ SCHAR_MIN -127 /* minimum value for 'signed char' */ SCHAR_MAX 127 /* maximum value for 'signed char' */ UCHAR_MAX 255 /* maximum value for 'unsigned char' */ SHRT_MIN -32767 /* minimum value for '(signed) short (int)' */ SHRT_MAX 32767 /* maximum ...
🌐
Cppreference
en.cppreference.com › w › cpp › language › types.html
Fundamental types - cppreference.com
For every value of type unsigned char in range [​0​, 255], converting the value to char and then back to unsigned char produces the original value.(since C++11) The signedness of char depends on the compiler and the target platform: the defaults for ARM and PowerPC are typically unsigned, ...
🌐
IME USP
ime.usp.br › ~pf › algorithms › chapters › int-and-char.html
What is a signed int? an unsigned int? a char?
Each block of s consecutive bytes is a word. Each word can have 28s different values. An unsigned int is an integer in the interval 0 . . 28s−1. Each unsigned int is represented in one word using binary notation. The value of s is given by the expression sizeof ...
🌐
Medium
medium.com › analytics-vidhya › what-is-char-signed-char-unsigned-char-and-character-literals-in-c-796034139b98
What is char , signed char , unsigned char , and character literals in C? | by mohamad wael | Analytics Vidhya | Medium
February 26, 2024 - All three types are different , but they have the same size of 1 byte . The unsigned char type can only store nonnegative integer values , it has a minimum range between 0 and 127 , as defined by the C standard.
🌐
Oracle
docs.oracle.com › javase › tutorial › java › nutsandbolts › datatypes.html
Primitive Data Types (The Java™ Tutorials > Learning the Java Language > Language Basics)
boolean: The boolean data type has only two possible values: true and false. Use this data type for simple flags that track true/false conditions. This data type represents one bit of information, but its "size" isn't something that's precisely defined. char: The char data type is a single 16-bit ...
🌐
W3Schools
w3schools.com › c › c_data_types_extended.php
C More Data Types (Extended Types)
*Note: The size of these types can differ between systems (for example, 2 or 4 bytes, or 4 or 8 bytes), depending on whether the computer is older or newer, 32-bit or 64-bit, and which compiler is used.
🌐
Quora
quora.com › In-C-what-an-unsigned-char-is-used-for-and-how-is-it-different-from-a-regular-char
In C++, what an unsigned char is used for and how is it different from a regular char? - Quora
Thus, a byte typically represents the unsigned cardinal values: 0 thru 255. Unlike when the language was originally defined for the PDP-11, since the C programming languages can now be used with a number of different ISA’s, if a programmer ...
🌐
W3Schools
w3schools.com › c › c_data_types_sizeof.php
C sizeof operator
int myInt; float myFloat; double myDouble; char myChar; printf("%zu\n", sizeof(myInt)); printf("%zu\n", sizeof(myFloat)); printf("%zu\n", sizeof(myDouble)); printf("%zu\n", sizeof(myChar)); Try it Yourself » · Note that we use the %zu format specifier to print the result, instead of %d. This is because the compiler expects the sizeof operator to return a value of type size_t, which is an unsigned integer type.
🌐
Quora
quora.com › How-is-unsigned-char-data-type-used-in-embedded-c-for-8-bit-microcontroller-as-a-decimal-integer-value-not-a-char-value
How is 'unsigned char' data type used in embedded c for 8 bit microcontroller as a decimal/integer value, not a char value? - Quora
Answer (1 of 13): From the beginning of time in C, whether you’re in a microcontroller environment or not, the char data type has always been usable as a one-byte integer. You can use a char variable to store the ASCII (or some other encoding’s) value of a character, or you can use it simply as a...
🌐
Cplusplus
cplusplus.com › forum › beginner › 283137
Get sizeof(unsigned char *) - C++ Forum
April 13, 2022 - Using sizeof is likely returning the size of the pointer, not the number of characters in the char array. ... strlen() doesn't compile with type unsigned char* - just char*. If it's really necessary to have the function with a unsigned char* param (which should probably be const unsigned char*) then you'll need to cast to char* for strlen() argument.
🌐
TutorialsPoint
tutorialspoint.com › cprogramming › c_data_types.htm
C - Data Types
CHAR_BIT : 8 CHAR_MAX : 127 CHAR_MIN ... : 127 SCHAR_MIN : -128 SHRT_MAX : 32767 SHRT_MIN : -32768 UCHAR_MAX : 255 UINT_MAX : 4294967295 ULONG_MAX : 18446744073709551615 USHRT_MAX : 65535 · The following table provides the ...