1

While reading the answer to the following question

Getting a buffer into a stringstream in hex representation:

I did not understand why there is a necessity to cast uint8_t to unsigned (or, as written in comments, even to unsigned char before that), while casting just to int is incorrect.

As I understand, no conversions at all would lead to interpreting uint8_t as an underlying type which can (must?) be some of 3 char variations and thus printing it as a character.

But what's wrong with casting to int? Any uint8_t value should always fit in int, so the conversion seems to be straightforward. Why sign-extension would make the code incorrect (mentioned in comments)?

UPD:

Just for reference, I figured what was talked about in the question I referred to is a case for signed char:

signed char num = -1;
std::cout << std::hex << static_cast<unsigned int>(static_cast<unsigned char>(num));

This would be written as more than 2 fs in absence of the second cast.

The point about 2's complement system seems to be incorrect though, as an integral conversion should apply to convert -1 to unsigned <smth>, and it adheres to the 2's complement system (i.e. when converting to e.g. uint8_t the result should always be 255 and thus be printed as 0xff, even having a different bit pattern).

ledonter
  • 1,269
  • 9
  • 27
  • Are you talking about casting between pointer types or casting between values of those types? – François Andrieux Jul 03 '17 at 19:35
  • 1
    The answers and comments are probably just being defensive in cases where the type of the buffer might be `char` (or some other non-`unsigned` type). You can safely cast the `uint8_t` to `int` without sign-extension issues. – Cornstalks Jul 03 '17 at 19:36
  • @FrançoisAndrieux conversion between the values of those types themselves (as it is done in the answer to the question I mentioned, i.e. conversion from `uint8_t` to `int` (`unsigned`)) – ledonter Jul 03 '17 at 19:37
  • @Cornstalks The comments are just plain wrong. If the type of the buffer is `char`, then casting it to either `int` or `unsigned int` is incorrect if you wish to get a result in `0`..`UCHAR_MAX`. –  Jul 03 '17 at 19:39

1 Answers1

6

You are correct that casting uint8_t to int will produce the exact same value as casting uint8_t to unsigned int. A simple loop to test all possible values of uint8_t, 0 ... 255, will confirm that the generated strings are 100% identical, and given that all implementations must support int values even higher than 255, there is no chance of some obscure implementation where limited range of int might cause problems.

  • And you can even do that **conversion** without a **cast**. – Pete Becker Jul 03 '17 at 20:13
  • @PeteBecker In general, yes. In the context of the question, no. When there are several function (or in this case operator) overloads, you may need casts to force a particular overload to be picked even if the conversion that you're performing is one that can be performed implicitly in other contexts. –  Jul 03 '17 at 20:20