Unsigned Keyword in C++

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



Leave a reply



Submit