-3

Actually compiling C++ under Visual 2013, the behaviour of std::hex (sticky operator) is not what I expected :

I'm trying to print a char as its hexadecial value, but I am forced to mask or cast my value to get the wanted behaviour.

So my question is not how to do, but why.

char valueInChar = 0xc8; //decimal 200
std::cout << std::hex << valueInChar; //prints out ╚
std::cout << std::hex << (valueInChar & 0xFF); //prints out c8
std::cout << std::hex << int(valueInChar); //also prints out c8

Is it a bug in visual implementation of the std? Am I confusing with std::ios::hex ?

Sandburg
  • 757
  • 15
  • 28
  • I didn't saw this answer after some research. I was searching with `std::hex`. – Sandburg Apr 06 '18 at 11:57
  • As far as I could tell by looking through the question, and answers in the duplicate: it is about the usage of `std::hex`. Even if it weren't: at it's core question is essentially the same: "how do I print `char` as hex?" – Algirdas Preidžius Apr 06 '18 at 11:58
  • I agree, but Matteo response better solve my interrogation, which is more "why" than "how can I do...". – Sandburg Apr 06 '18 at 12:02
  • Does duplicating meens bad question? Downvoting is for bad questions or for duplicated questions ? – Sandburg Apr 06 '18 at 12:04
  • 1
    Technically? Depends. Hover over the downvote button with a mouse, what do you see? "This question does not show any research effort; it is unclear or not useful." One can argue, that if the duplicate exists (especially, if it can be easily found, with pretty much the same terms, that exist in the question) - the asker didn't do enough research, which can become a reason for a duplicate. However, if you, in the question itself, acknowledged, that your question is similar to question X, and then proceeded to explain **why** is it different from it: it is a different situation. – Algirdas Preidžius Apr 06 '18 at 12:14

1 Answers1

4

The operator<< overload for char prints character values as they are, so they aren't formatted as integers (which would be affected by formatting flags), but as characters.

The row with the masking happens to work because virtually all arithmetic and bitwise operators promote small integers (signed/unsigned char and short) to "regular sized" ones (int or unsigned int, according to some rules), so there you are actually invoking the operator<< for int.

To make it work without masking, just add a cast to int.

std::cout << std::hex << int(valueInChar);
Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
  • I do have some undefined behaviour in this other situation, not related to streams : `short fullValue = ((short(valueHigh) << 8) | short(valueLow));` depending on the origin of the 2 char values... only the mask solve it, not the cast as short... – Sandburg Apr 06 '18 at 12:36
  • 2
    @Sandburg Yes, because [left shifts on signed values are undefined behaviour](https://msdn.microsoft.com/en-us/library/336xbhcz.aspx): "If you left-shift a signed number so that the sign bit is affected, the result is undefined." - so you have to be very careful with your mask and shift amount. Right shifts on signed numbers also have their peculiarities, which is why it is best to only shift unsigned integers. – Max Langhof Apr 06 '18 at 12:41