读书人

这两条话语有什么区别

发布时间: 2013-07-21 21:55:43 作者: rapoo

这两条语句有什么区别?
下面这两条语句有什么区别?

unsigned long x = 0;

....


1. x++;
2. (*(unsigned int*)&x)++;

为什么要使用第二种, 而不是用第一种?
[解决办法]
你觉得两个语句效果一样?
需要知道 unsigned long 与 unsigned int 的字节数一般是不一样的,以分别为八字节和四字节为例,第一条语句是把 x 的地址开始的八个字节进行加一,而第二条语句是把从 x 开始的四个字节进行加一,结果当然不一样。
[解决办法]
在 VC2005 下完全没有区别:


0041138C rep stos dword ptr es:[edi]
unsigned long x = 0;
0041138E mov dword ptr [ebp-8],0
x++;
00411395 mov eax,dword ptr [ebp-8]
00411398 add eax,1
0041139B mov dword ptr [ebp-8],eax
(*(unsigned long*)&x)++;
0041139E mov eax,dword ptr [ebp-8]
004113A1 add eax,1
004113A4 mov dword ptr [ebp-8],eax

[解决办法]
没什么区别,第二种写法有点炫耀语法的感觉,故意把简单的东西复杂化,以显示水平很高。

引用:
下面这两条语句有什么区别?

unsigned long x = 0;

....


1. x++;
2. (*(unsigned int*)&x)++;

为什么要使用第二种, 而不是用第一种?

[解决办法]
应该是同步互斥吧
[解决办法]
引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

在 VC2005 下完全没有区别:
 


0041138C rep stos dword ptr es:[edi]
unsigned long x = 0;
0041138E mov dword ptr [ebp-8],0
x++;
00411395 mov eax,dword ptr [ebp-8]
00411398 add eax,1
0041139B mov dword ptr [ebp-8],eax
(*(unsigned long*)&x)++;
0041139E mov eax,dword ptr [ebp-8]
004113A1 add eax,1
004113A4 mov dword ptr [ebp-8],eax



既然完全没区别, 那为什么要写成第二种呀!


你在哪里看到这种写法的?


Linux 的源代码里, 这里可以在线查看 http://lxr.linux.no/linux-old+v2.4.31/kernel/timer.c#L699


这个在 <<Linux 内核情景分析>> 中倒是有一段解释:
这两条话语有什么区别
网上也有类似的说法: http://blog.sina.com.cn/s/blog_48e0a24b010003lc.html

不过, 我在 gcc 下试验发现也没有生成 inc 语句的汇编.

而且新版本的 Linux 源代码中也不是这种方式了.
http://lxr.linux.no/linux-bk+v2.6.11.5/kernel/timer.c#L920

所以, 两种解释:
1. 开发内核的作者无心之失, 国内写书的作者想当然耳, 凭猜测写书.
2. 在 gcc 的某个历史版本中有这种处理方法, 或在某个选项下面会这样处理. Linux 的源代码本事是严重依赖 gcc 编译器的.
[解决办法]
引用:
你觉得两个语句效果一样?
需要知道 unsigned long 与 unsigned int 的字节数一般是不一样的,以分别为八字节和四字节为例,第一条语句是把 x 的地址开始的八个字节进行加一,而第二条语句是把从 x 开始的四个字节进行加一,结果当然不一样。

和你说的恰好相反。由于常见的intel CPU是小端在前,最低位总是第一个字节。所以这两种情况都是第一个字节加一。

读书人网 >C语言

热点推荐