Cout not printing number
Asked Answered
H

3

16

Issue

I'm getting no output from a simple cout, whereas a printf will always print the number:

std::cout << variableuint8;  // prints nothing
printf("%u", variableuint8); // prints the number

I've never run into this behavior before, and while I have a work around I would like to understand it.

Context:

Yay, pointers. So it may be a little more involved than as stated. Here's the context - I don't think it should matter, by the time cout and printf get the info it's dereferenced to a simple unsigned char. This is probably more information than needed to resolve the issue, but I wanted to be complete on the off chance that it was relevant.

typedef unsigned char   UInt8;
typedef unsigned short  UInt16;

typedef struct{
   UInt8   len;
   // some other definitions. sizeof(DeviceNotification) <= 8
}DeviceNotification;

UInt8 somerandomdata[8];
DeviceNotification * notification;

notification = (DeviceNotification *) somerandomdata;

std::cout << "Len: (" << notification->len << ")\n";
printf("Len: (%u)\n", notification->len);

The random data is initialized elsewhere. For this output, the first byte in the array is 0x08:

Output:

Len: ()
Len: (8)

Environment

  • Development machine:
    • OS X 10.6.8
    • Compiler LLVM 1.7
    • Xcode 3.2.6
  • Test machine:
    • OS X 10.6.8
Humpage answered 9/11, 2011 at 13:31 Comment(4)
I just wanna ask is the following line defined in C++? ` notification = (DeviceNotification *) somerandomdata;` doesn't this line invoke undefined behavior if the alignment is not the required alignment of DeviceNotification?Coldshoulder
@AraK These are running on x86, which allows unaligned memory accesses. They may be slower, as they may require two reads of the memory bus to get a value that is split across the boundary, but it works just fine. You can perform some experiments to demonstrate this - if you do, let us know if there is a speed difference.Humpage
Thanks, that is interesting. It would be nice to write such a micro-benchmark.Coldshoulder
Even on machines that do have strict alignment requirements, these tend to be applied to fundamental types and not structs. In particular, accessing a byte-size member (such as UInt8 len) is safe.Chane
B
12

It's printing the char as a character.

#include <iostream>

int main() {
        unsigned char c = 0x41;
        std::cout << c << std::endl;
        return 0;
}

This prints 'A' to the stdout.

Although in that case, your code should print Len: (*), and I did have verified it prints Len: (*).


Edit: Since in character encodings like ASCII or UTF-8 your console is likely using, the character corresponding to 8 (Backspace) is not visible, it will look like it's not printed.

(In some cases it may cause the previous character (the () to disappear because it is a backspace character. In DOS it may show ◘)

Bossism answered 9/11, 2011 at 13:36 Comment(3)
That's the issue. You are right about my example output being incorrect - I've changed it to demonstrate the problem as I was actually experiencing it.Humpage
It is not a real point. The example program should print 42 (*), but it does not.Subjugate
@tyz I made an error in my example - Kenny is correct. I've modified my example with the actual value I was dealing with. Sorry for the confusion.Humpage
C
4

Have you tried to cast it into int, to avoid depending on the char type that is used by the implementation:

std::cout << (int)variableuint8;

Here is an explanation of what is going on: What is an unsigned char?

To get an idea, your implementation is using unsigned char as char. The ASCII code for 0x08 is the backspace control character, and of course it is not a printable character, that is why you don't see an output in the case of std::cout.

Coldshoulder answered 9/11, 2011 at 13:37 Comment(1)
std::cout << +variableuint8; would be simplerBugs
M
3

Would std::cout << "Len: (" << (unsigned short)notification->len << ")\n"; print the correct value? I guess casting to an integer is what might be looking for.

Monica answered 9/11, 2011 at 13:33 Comment(1)
Yes, and this is the correct fix. In my case I cast (UInt16) but the effect is the same.Humpage

© 2022 - 2024 — McMap. All rights reserved.