Chinaunix首页 | 论坛 | 博客
  • 博客访问: 990913
  • 博文数量: 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:需要说明某些平台有特定的数据对齐要求,会执行崩溃吗?当然不需要^_^

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

网友评论2012-11-23 16:50:34

周星星
如果那段程序的str结果是"11234467",那运算过程一定按我说的方式执行的。
----- 确实是按照你说的方式执行的,我的文章正文中早就写明了呀,估计你没仔细看。但是我不明白的是,为什么按你说的方式执行,那就不算bug呢?

呵呵,你和她很像吧?^_^,不要生气哦。
------ 当然不生气,但我不理解为什么你说我和她很像?当然,这个话题我不理解也无所谓。

来源和目标重叠,c++有标准规定也能运算正确吗?
------ 我想我明白了,你认为这是一个“数据重叠”引发的未定义行为。但既然你是这么认为的,那你一开始就别什么汇编不汇编,你直接说得了呀!未定义行为看汇编有啥用呢?
说实话,这一点上我有点生气,你拉扯完全无关的东西浪费了我太多太多时间去琢磨你的想法。

网友评论2012-11-23 16:50:26

Jack.arain
“看错误的汇编用什么用?这段汇编是根据其作者错误的想法编译出的。 ”
如果那段程序的str结果是"11234467",那运算过程一定按我说的方式执行的。

另外,你举的例子太挫了。让我想起了我班一女生,她写了一段类似下面这样的程序:
int a = 2147483647 + 1;
a变负了,于是她跟大家说,vc有bug。
呵呵,你和她很像吧?^_^,不要生气哦。

再说了,来源和目标重叠,c++有标准规定也能运算正确吗?
最后,计算机程序是面对程序员的,程序员必须对一些东西要能理解,能想当然的话,人人都可以编程了,是吧?

网友评论2012-11-23 16:50:18

周星星
看错误的汇编用什么用?这段汇编是根据其作者错误的想法编译出的。
是不是错误应该根据C/C++标准中的规定来判断^_^。

举个例子:
老师布置一道题目是求 27 + 7 = ?
小明马虎,忘了进位,得出错误的结果 24
另一个人说:如果不进位的话结果确实是24呀,所以27+7=24可以理解,不算错误。

网友评论2012-11-23 16:50:09

Jack.arain
这不算是bug,也很容易理解
*(__int64*)(str+1) = *(__int64*)(str+0);
稍对asm有了解就清楚,在win32下,这个执行过程是以eax作为中间寄存器来保存中间值,大至过程如下(伪代码)
mov         eax, str
mov         str + 1, eax // 此时str内容为"1123467"
mov         eax, str + 4 // eax = "467\0"
mov         str + 1+ 4, eax // 此时str为"11234467"

网友评论2012-11-23 16:50:00

mslk
将 *(__int64*)(str+1) = *(__int64*)(str+0); 分解为
*(__int32*)(str+5) = *(__int32*)(str+4);
*(__int32*)(str+1) = *(__int32*)(str+0);
就OK了

看来关于__int64的赋值,编译的代码要根据两个变量地址来决定分解为两个__int32的操作的顺序