Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How portable is casting -1 to an unsigned type?

Tags:

c++

The other day, I came across this construct:

static_cast<size_type>(-1)

in some example C++ code, which is likely (depending on the details of where size_type is from) to be equivalent to the following C:

(size_t)(-1)

As I understand it, it works based on the fact that the representation of -1 in twos complement arithmetic is 11111...1, for as many bits as you have, so this is a quick way of getting the maximum value that an unsigned type like size_t can hold. However, my understanding is also that C doesn't guarantee that twos complement will be used; if the C implementation uses one's complement, this will be 1 less than the the maximum value, and if it's using signed magnitude, it will be just over half the maximum value.

Is there some wrinkle that I'm missing that insures that this works right regardless of the representation of signed integers being used? Does it differ between C and C++ (many surprising things do)?

like image 789
Pillsy Avatar asked Nov 03 '09 15:11

Pillsy


People also ask

Is it safe to cast unsigned to signed?

As you can see, even assuming the same number of bits used to store an integer, signed and unsigned integers have different positive value limits. Converting a large positive unsigned number to a signed one can lead to bogus results (like negative numbers!) and hard-to-find bugs.

What is uintptr_ t used for?

The intptr_t and uintptr_t types are extremely useful for casting pointers when you want to do address arithmetic. They should be used instead of long or unsigned long for this purpose. Use of uintptr_t for casting is usually safer than intptr_t , especially for comparisons.

What is an unsigned int in C?

C and C++ are unusual amongst languages nowadays in making a distinction between signed and unsigned integers. An int is signed by default, meaning it can represent both positive and negative values. An unsigned is an integer that can never be negative.

What is the range of signed integer?

A signed integer is a 32-bit datum that encodes an integer in the range [-2147483648 to 2147483647].


2 Answers

The requirements on unsigned arithmetic guarantee that casting -1 to an unsigned type will produce the largest number possible for the target type. C99, §6.2.5/9: "...a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type."

This is the same in C and C++ (in the C++ standard, similar wording is found in footnote 41 -- it's not normative, but it's explaining other wording that is).

like image 180
Jerry Coffin Avatar answered Sep 19 '22 01:09

Jerry Coffin


To be on a "safe" side and do it "right" (C++) way, worth looking at STL:

std::numeric_limits<size_t>::max()
like image 32
Aleksei Potov Avatar answered Sep 17 '22 01:09

Aleksei Potov