Unsigned keyword in C++
From the link above:
Several of these types can be modified using the keywords signed, unsigned, short, and long. When one of these type modifiers is used by itself, a data type of int is assumed
This means that you can assume the author is using ints.
Confusion in unsigned keyword in C/C++
Each printf
format specifier requires an argument of some particular type. "%d"
requires an argument of type int
; "%u"
requires an argument of type unsigned int
. It is entirely your responsibility to pass arguments of the correct type.
unsigned int i = -12;
-12
is of type int
. The initialization implicitly converts that value from int
to unsigned int
. The converted value (which is positive and very large) is stored in i
. If int
and unsigned int
are 32 bits, the stored value will be 4294967284
(232-12).
printf(" i = %d\n",i);
i
is of type unsigned int
, but "%d"
requires an int
argument. The behavior is not defined by the C standard. Typically the value stored in i
will be interpreted as if it had been stored in an int
object. On most systems, the output will be i = -12
-- but you shouldn't depend on that.
printf(" i = %u\n",i);
This will correctly print the value of i
(assuming the undefined behavior of the previous statement didn't mess things up).
For ordinary functions, assuming you call them correctly, arguments will often be implicitly converted to the declared type of the parameter, if such a conversion is available. For a variadic function like printf
, which can take a varying number and type(s) of arguments, no such conversion can be done, because the compiler doesn't know what type is expected. Instead, arguments undergo the default argument promotions. An argument of a type narrow than int
is promoted to int
if int
can hold all values of the type, or to unsigned int
otherwise. An argument of type float
is promoted to double
(which is why "%f"
works for both float
and double
arguments).
The rules are such an argument of a narrow unsigned type will often (but not always) be promoted to (signed) int
.
unsigned char a=200, b=200, c;
Assuming 8-bit bytes, a
and b
are set to 200
.
c = a+b;
The sum 400
is too bit to fit in an unsigned char
. For unsigned arithmetic and conversion, out-of-range results are reduced to the range of the type. c
is set to 144
.
printf("result=%d\n",c);
The value of c
is promoted to int
; even though the argument is of an unsigned type, int
is big enough to hold all possible values of the type. The output is result=144
.
Do i need 'unsigned' keyword with uintXX_t?
You do not need to use unsigned
and in fact, you can not use it.
Only the fundamental types may be modified with the signed
and unsigned
(also long
and short
) keywords.
Aliases of the standard types can not be modified using those keywords and that includes the fixed width aliases.
If you write unsigned int32_t
, then the compiler will parse this as a variable with type unsigned
(which is shorthand for unsigned int
) and the name of the variable will be int32_t
. unsigned int32_t variable_name
would be a syntax error.
What does the unsigned keyword do here?
unsigned
simply means that the number won't become negative. Yeah, number, because a char
really is just an 8-bit integer.
So when unsigned
, every bit is used in the non-negative range, which will go from 0 to 255. When you leave out and use a signed
(default) char, the range will go from -128 to 127, thus it will always be less than 128 and go into an infinite loop.
The beep you hear is due to the char of value 7 being "printed".
An int
, on the other hand, even when signed goes all the way from -2.147... billions to +2.147 billions, so it will iterate normally until reaching 128 and stopping.
Omitting the datatype (e.g. unsigned instead of unsigned int)
unsigned
is a data type! And it happens to alias to unsigned int
.
When you’re writing unsigned x;
you are not omitting any data type.
This is completely different from “default int
” which exists in C (but not in C++!) where you really omit the type on a declaration and C automatically infers that type to be int
.
As for style, I personally prefer to be explicit and thus to write unsigned int
. On the other hand, I’m currently involved in a library where it’s convention to just write unsigned
, so I do that instead.
Can the unsigned keyword be used in non-obvious ways?
No, it can't be used with classes or structs since they're not integral types. All a template can do with it is make an int unsigned. I think it was chosen as a separate keyword since it can be applied to any integer type (char, int, long, long long), thereby achieving with one keyword what would have required four more. Its meaning is also immediately evident, whereas uint, uchar, etc. aren't necessarily. And keep in mind it can also be used by itself without a qualifier, in which case unsigned int is assumed.
Does the unsigned keyword affect the result of sizeof?
Both languages guarantee that signed and unsigned variants of a corresponding standard integer type have the same size.
C++, committee draft n3337, 3.9.1/3:
3 For each of the standard signed integer types, there exists a corresponding (but different) standard un-
signed integer type: “unsigned char”, “unsigned short int”, “unsigned int”, “unsigned long int”,
and “unsigned long long int”, each of which occupies the same amount of storage and has the same
alignment requirements (3.11) as the corresponding signed integer type45; that is, each signed integer type
has the same object representation as its corresponding unsigned integer type. [...]
For C, the wording is very similar
Taken from draft n1570, 6.2.5/6:
For each of the signed integer types, there is a corresponding (but different) unsigned
integer type (designated with the keyword unsigned) that uses the same amount of
storage (including sign information) and has the same alignment requirements. The type
_Bool and the unsigned integer types that correspond to the standard signed integer
types are the standard unsigned integer types. The unsigned integer types that
correspond to the extended signed integer types are the extended unsigned integer types.
The standard and extended unsigned integer types are collectively called unsigned integer
types.
Placement of the unsigned keyword
First, you cannot create your own types that are marked unsigned
/signed
, so it could only apply to the pre-existing type.
Second, yes it is valid to swap the position of that qualifier:
[C++11: 7.1.6.2/3]:
When multiple simple-type-specifiers are allowed, they can be freely intermixed with other decl-specifiers in any order. [..]
So, the two declarations are equivalent.
Related Topics
Lru Implementation in Production Code
C++ Integer->Std::String Conversion. Simple Function
Do Negative Numbers Return False in C/C++
C++11 Memory_Order_Acquire and Memory_Order_Release Semantics
How to Count Lines of a File in C++
Inheriting Private Members in C++
Header File Inclusion Static Analysis Tools
Passing Optional Parameter by Reference in C++
C++ Can Compilers Inline a Function Pointer
Why Is "\" an Escape Sequence in C/C++
Why Does Int Main() {} Compile
Why Not Just Use Random_Device
Dereferencing a Pointer When Passing by Reference
Use of Typename Keyword with Template Function Parameters
Maximum Number of Parameters in Function Declaration
Use of Typename Keyword with Template Function Parameters
How to Install/Configure Opencv3.2.0 with C++, Visual Studio 2017