Chinaunix首页 | 论坛 | 博客
  • 博客访问: 988154
  • 博文数量: 158
  • 博客积分: 4380
  • 博客等级: 上校
  • 技术积分: 2367
  • 用 户 组: 普通用户
  • 注册时间: 2006-09-21 10:45
文章分类

全部博文(158)

文章存档

2012年(158)

我的朋友

分类: C/C++

2012-11-23 16:48:26

#include

int main( void )
{
    char str[16] = "1234567";
   
    *(__int64*)(str+1) = *(__int64*)(str+0);

    std::cout << str << std::endl;
}

应该(注1)输出11234567,但 VS200X 在32位平台下输出为11234467
VS200X 将 *(__int64*)(str+1) = *(__int64*)(str+0); 分解为
*(__int32*)(str+1) = *(__int32*)(str+0);
*(__int32*)(str+5) = *(__int32*)(str+4);
这显然不对

注1:需要说明某些平台有特定的数据对齐要求,会执行崩溃吗?当然不需要^_^

阅读(1740) | 评论(10) | 转发(0) |
给主人留下些什么吧!~~

网友评论2012-11-23 16:49:51

周星星
:)避开VC的bug是一回事,VC有没有这个bug是另一回事。

网友评论2012-11-23 16:49:44

jeffer

__int64 tmp = *(__int64*)(str+0);
*(__int64*)(str+1) = tmp;  

在 debug build   , 正確輸出 11234567
在 release build , 錯誤輸出  11234467

volatile __int64 tmp = *(__int64*)(str+0);
*(__int64*)(str+1) = tmp;  

加上 volatile 防止最佳化, 就不分 debug/release build
皆得到正確輸出

网友评论2012-11-23 16:49:35

周星星
每个人第一眼看到这代码自然会如你这样想,我一开始也认为是“未定义”行为。
不过仔细对比一下,*(__int64*)(str+0) 对operator= 而言是个值,因此根本不存在所谓的重叠。

如果不想被*(__int64*)(str+0)迷住了眼,那么写成
__int64 tmp = *(__int64*)(str+0);
*(__int64*)(str+1) = tmp;
在VS200X的release下同样输出错误数据。

网友评论2012-11-23 16:49:28

jeffer
精典的搬石頭砸到自己 , 當來源和目標重叠.
不能稱為bug, 這算是 沒定義, 寫碼自己要避免
就好比
   memcpy( src , src+4 , 5);
   memcpy( src+4 , src , 5);

网友评论2012-11-23 16:49:06

局部变量
rt