0

I have the following code:

#include <iostream>
using namespace std;

typedef uint8_t byte;

int main()
{
    byte x[5] = {0,1,2,3,4};

    byte* xptr = x;

    for (int i = 0; i < 5; ++i)
    {
        cout << "\n x[" << i
            << "] = " << *xptr
            << " at " << xptr;
        xptr = xptr + 1;
    }

    xptr = xptr - 5;

    cout << "\n\n\n";
}

the output contains strange characters as follows:

enter image description here

I expect this is because the underlying type of uint8_t is related to the char data type.

I know I can do some explicit type conversions to get it work as follows:

cout << "\n x[" << i
    << "] = " << (int)*xptr
    << " at " << (void*)xptr;

also, I know I can make class to handle it myself.

enter image description here

However, I prefer not to use type conversion or make a special class if possible.

I went through the Internet and I got this on StackOverflow, but it did not help.

So, is there a native way to have an 8 bit integer type on C++ that acts exactly like int and short with all standard libraries? or this is just one of the countless C++ unconvincing* feature absence?

*at least to me.

Community
  • 1
  • 1
Shadi
  • 1,701
  • 2
  • 14
  • 27
  • There is a proposal for [`std::byte`](http://en.cppreference.com/w/cpp/types/byte) in the next C++17 standard. – vsoftco Apr 24 '17 at 15:14
  • The proposed `std::byte` is not an integer though. – Gert Wollny Apr 24 '17 at 15:23
  • Signed or unsigned `char` already represent 8 bit integer natively (on most platforms). It is unclear what you are missing. – Slava Apr 24 '17 at 15:24
  • @Slava: you cannot print their value as integer directly, and they are overlapping with `char`. I am looking for something like int and short but one byte in size. – Shadi Apr 24 '17 at 15:30
  • @GertWollny And that's the whole point, it won't be a typedef for `char` as `uint8_t` probably is, or, in other words, it will be a "strong type". – vsoftco Apr 24 '17 at 15:49
  • @Shadi you "cannot" print because `std::ostream` treat char as symbol, not because they are not native integers. So again what are you missing from char "not being" real integer? – Slava Apr 24 '17 at 15:52
  • You are absolutely right @Slava. However, this is how the overlapping happens. Anyway, I got your point and it is true. – Shadi Apr 24 '17 at 16:05
  • @vsoftco as it is written in the reference you gave, `std::byte` is not an arithmetic type, and since OP asked explicitly for an 8 bit *integer* type I guess that would include arithmetic operations. – Gert Wollny Apr 27 '17 at 09:24

4 Answers4

2

If you're concerned only with the readable output format, and you don't want to type the cast expression every time, you can simply prepend the unary operator:

cout << +x;

This performs an implicit conversion to int.

Example:

#include <iostream>
int main()
{
    char ch = 'D';
    std::cout << ch << "\n";   // Displays "D"
    std::cout << +ch << "\n";  // Displays "68"
}

Sadly, there's no ostream option like the std::dec I/O manipulator to do this automatically.

Dan
  • 333
  • 4
  • 12
  • Thanks @Dan. This is a clever trick, however, it works only for `char` but not for `char*`. – Shadi Apr 25 '17 at 06:15
  • Correct. Side note: You may want to edit your question or it's title to indicate that you're specifically interested in printing numeric output from an array, and not just the actual underlying memory size. – Dan Apr 25 '17 at 08:04
  • I'm curious, what is your reason for avoiding the type cast? – Dan Apr 25 '17 at 08:09
  • Hey @Dan, I made a simple class named byte to imitate other integer types with having the size of the byte. It worked, but it still needs more work and it is not a standard. I do not want to use `char` and casting for the sake of my students. a lot of them are not to be pro programmers, yet they need C++ as part of their curriculum. They are confused because of the name `char`. and because of the output. Casting adds a bit more confusion to them. also, I am considering your side note. Thanks. – Shadi Apr 25 '17 at 10:23
  • Interesting. So are you not teaching casting at all? (I can't imagine how you could teach C++ without it, so I'm curious from a teaching standpoint.) Also, if you're using Visual Studio, there is a Microsoft-specific type `__int8`, which is an actual integral and not a typedef. – Dan Apr 25 '17 at 13:01
  • Hey, @Dan, No. I am teaching casting. however, I am trying to make every example explain the main idea only. Because the course time is relatively short there is not enough time to absorb everything. In such case, simplifying plays a major rule in teaching the most possible contents with the most possible understanding. However, Chapters Exercise are designed to get student use most of what they learned. Of course there are smart students who get it on the fly, but I care also about students who need slower pace and clearer examples. :) – Shadi Apr 25 '17 at 17:52
0

for the sake of the readability you can use hexadecimal base and cast to int:

for (int i = 0; i < 5; ++i)
    {
        cout << "\n x[" << i << "] = " << (int)*xptr << " at " << hex << (int)xptr;
        xptr++;
    }

the output:

 x[0] = 0 at 8ffeb0
 x[1] = 1 at 8ffeb1
 x[2] = 2 at 8ffeb2
 x[3] = 3 at 8ffeb3
 x[4] = 4 at 8ffeb4
ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97
0

uint8_t and int8_t are your real 8-bit integers on C++. But because they are typedefs over chars (if they exist at all, it's not guaranteed), they are interpreted and treated as characters by the standard library. Unfortunately, you'll just have to use a cast.

Side note: you don't need to use pointers here, use array indices:

for (int i = 0; i < 5; ++i)
{
    cout << "\n x[" << i
        << "] = " << (int)x[i]
        << " at " << hex << &x[i] << dec;
}

Side note #2: C++17 will introduce a std::byte type, but it is just a strange wrapper around unsigned char using enum class. It only implements bitwise operators and conversion functions to and from integer types, so it is not what you're looking for.

  • I know @InternetAussie I can use indices, I just used pointer for the sake of the example. your info is appreciated though. – Shadi Apr 24 '17 at 15:32
0

For c++11, there is int_8/uint_8 type, please read this webpage:

https://en.cppreference.com/w/cpp/types/integer

Y00
  • 666
  • 1
  • 7
  • 23