【发布时间】:2011-12-25 07:54:06
【问题描述】:
问题
我没有从一个简单的 cout 得到任何输出,而 printf 总是会打印数字:
std::cout << variableuint8; // prints nothing
printf("%u", variableuint8); // prints the number
我以前从未遇到过这种行为,虽然我有一个解决办法,但我想了解它。
上下文:
是的,指针。所以它可能比所说的要复杂一些。这是上下文-我认为这无关紧要,到 cout 和 printf 获取信息时,它已被取消引用为简单的无符号字符。这可能比解决问题所需的信息更多,但我希望它是相关的。
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);
随机数据在别处初始化。对于这个输出,数组中的第一个字节是 0x08:
输出:
Len: ()
Len: (8)
环境
- 开发机:
- OS X 10.6.8
- 编译器 LLVM 1.7
- Xcode 3.2.6
- 测试机:
- OS X 10.6.8
【问题讨论】:
-
我只想问下面这行是用C++定义的吗? ` notification = (DeviceNotification *) somerandomdata;` 如果对齐不是
DeviceNotification的必需对齐,此行不会调用未定义的行为吗? -
@AraK 这些在 x86 上运行,允许未对齐的内存访问。它们可能更慢,因为它们可能需要两次读取内存总线才能获得跨边界拆分的值,但它工作得很好。您可以进行一些实验来证明这一点 - 如果您这样做了,请告诉我们是否存在速度差异。
-
谢谢,这很有趣。能写出这样一个微基准就好了。
-
即使在有严格对齐要求的机器上,这些往往也适用于基本类型而不是结构。特别是,访问字节大小的成员(例如
UInt8 len)是安全的。