在stackoverflow上看到这个问题
http://stackoverflow.com/questions/22758232/why-is-access-once-so-complex

原答主已经回答的很仔细了,不过还不够直观,这里做个试验

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3
 4 //加子函数防止变量优化没了
 5 void pfunc(int a, int b)
 6 {
 7         int i = 0;
 8         int sum = 0;
 9         for (i = 0; i < b; i++)
10         {
11                 sum += a * i;
12         }
13
14         printf("sum %x\n", sum);
15 }
16
17 int main()
18 {
19         int i = 0x102;
20         int a = (volatile int)i;
21         int b = *(volatile int *)&i;
22
23         pfunc(a, b);
24 } 

在arm平台上编译并截取main()的汇编
R0与R1为函数入参,从ldr指令看两者获取i的方式相同

 1 000083ec <main>:
 2     83ec:        e92d4800         push        {fp, lr}
 3     83f0:        e28db004         add        fp, sp, #4
 4     83f4:        e24dd010         sub        sp, sp, #16
 5     83f8:        e59f3028         ldr        r3, [pc, #40]        ; 8428 <main+0x3c>
 6     83fc:        e50b3010         str        r3, [fp, #-16]
 7     8400:        e51b3010         ldr        r3, [fp, #-16]
 8     8404:        e50b3008         str        r3, [fp, #-8]
 9     8408:        e51b3010         ldr        r3, [fp, #-16]
10     840c:        e50b300c         str        r3, [fp, #-12]
11     8410:        e51b000c         ldr        r0, [fp, #-12]
12     8414:        e51b1008         ldr        r1, [fp, #-8]
13     8418:        eb000003         bl        842c <pfunc>
14     841c:        e1a00003         mov        r0, r3
15     8420:        e24bd004         sub        sp, fp, #4
16     8424:        e8bd8800         pop        {fp, pc}
17     8428:        00000102         andeq        r0, r0, r2, lsl #2 

加入O1编译

 1 00008430 <main>:
 2     8430:        e52de004         push        {lr}                ; (str lr, [sp, #-4]!)
 3     8434:        e24dd00c         sub        sp, sp, #12
 4     8438:        e59f0010         ldr        r0, [pc, #16]        ; 8450 <main+0x20>
 5     843c:        e58d0004         str        r0, [sp, #4]
 6     8440:        e59d1004         ldr        r1, [sp, #4]
 7     8444:        ebffffe8         bl        83ec <pfunc>
 8     8448:        e28dd00c         add        sp, sp, #12
 9     844c:        e49df004         pop        {pc}                ; (ldr pc, [sp], #4)
10     8450:        00000102         andeq        r0, r0, r2, lsl #2 

可见此时R0与R1的来源不同,R0(a)的值是将i入栈时候的值,如果此时(在ldr之后)多线程修改该值即入参就出错了(当然在这个例子中不可能,因值是全局初始化的在代码段里,但意思是这个意思),而R1仍从堆栈里取该值保证变量的正确性

结论:

1. 由此可见内核使用*(volatile typeof(x) *)(&x)的方式是必要的并且简化版((volatile typeof(x)(x))并没有起到意想中的效果(因为x是做为取出的值去做强制类型转换,而当它转换时可能已经在寄存器里了)

2. 理解这类问题最好方法就是写个demo直接反汇编,一切都清楚了

转载于:https://www.cnblogs.com/Five100Miles/p/8460324.html

(volatile int)(x)与*(volatile int *)(x)相关推荐

  1. const volatile同时限定一个类型int a = 10

    const和volatile放在一起的意义在于: (1)本程序段中不能对a作修改,任何修改都是非法的,或者至少是粗心,编译器应该报错,防止这种粗心: (2)另一个程序段则完全有可能修改,因此编译器最好 ...

  2. java volatile 多线程,java多线程-volatile的使用

    volatile关键字 主要作用: ​ 1.保证数据之间的可见性. ​ 2.禁止指令重排序. 1.可见性 2.做个小的测试public class VolatileTest implements Ru ...

  3. java volatile 原子性_为什么volatile不能保证原子性而Atomic可以?

    在上篇<非阻塞同步算法与CAS(Compare and Swap)无锁算法>中讲到在Java中long赋值不是原子操作,因为先写32位,再写后32位,分两步操作,而AtomicLong赋值 ...

  4. const int * 、int * const、int const* 、const int a(){ } 和int a()const { }的区别和联系

    前言:很多人都把const int * .int * const.int const* 的区别和联系搞混,我自己在学习C++的过程中,也经常性          弄不 清楚,今天特意总结一下,作为学习 ...

  5. java indexof int,int indexOf(String str, int fromIndex)

    int indexOf(String str, int fromIndex) 描述 (Description) java.lang.String.indexOf(String str, int fro ...

  6. int * * a[10] int * (*a)[10]和 int(*a[10])() 是什么意思

    int* (*a)[10]; a是一个指向包含10个int型指针元素的数组. 比如: #include <stdio.h>int main() {// 定义数组,包含10个int*int* ...

  7. 编写一个函数itob(int n,char s[], int b),将整数n转换为以b进制的数。保存到s中。...

    void Reverse(char *left, char* right) {while (left < right){char tmp = *left;*left = *right;*righ ...

  8. const int、const int *、int *cosnt、const int * const、const int 的区别

    2018-01-04 创建人:Ruo_Xiao 2018-10-17 修改人:Ruo_Xiao 邮箱:xclsoftware@163.com 修改内容:增加对 delete 指向常量的指针的可行性的说 ...

  9. int a = 0 与 int a(0) int a(b)

    偶然看书发现了int a(0);这种写法,当时感觉很奇怪,于是网上搜索一番,发现了其中原因 C++ 延续了C 的编程思想,所以说有两套编程体系,面向对象及面向过程 int a = 0: 这种写法,就是 ...

最新文章

  1. Jsp----注册登陆
  2. python爬虫xpath提取数据_python爬虫三大解析库之XPath解析库通俗易懂详讲
  3. markdown 换行_markdown傻瓜指南(github)
  4. 计算机主机安装系统安装系统安装软件,电脑安装软件时提示安装过程出错系统设置未被修改怎么办...
  5. 聚类算法——Birch详解
  6. CSDN、博客园等6大技术博客平台的写作体验测评 1
  7. python按键暂停程序_汇总程序员学习python必备的42个快捷键,看完收获满满
  8. 来自lombok的注解(解决idea中的找不到get,set方法,找不到log的问题)
  9. springboot学习笔记2106版
  10. android 通讯录恢复,通讯录恢复
  11. Powershell————2、Powershell交互式
  12. 笔记本计算机没有没有显示无线网络连接,笔记本没有无线网络连接,教您笔记本没有无线网络连接...
  13. Python中Round函数:怎么解释?怎么用?
  14. 【预测师】的时间管理方法论(泰山版)
  15. CF643D Bearish Fanpages
  16. Oracle 11g用exp无法导出空表的处理方法
  17. 进位位判别法_图解停车进位方法及如何确定车距
  18. WPS文档设置空格下划线
  19. 第十章 DirectX 绘制简单场景,地形,天空盒和跟随摄像机(下)
  20. .net sqlite 下载地址

热门文章

  1. SAP MM公司间STO里的交货单自动创建?
  2. 宁‘内卷‘,勿‘躺平‘
  3. 演讲实录丨清华大学朱小燕教授:对话系统现状与展望
  4. 京东开源人脸识别工具包:覆盖最强模型,支持训练跑分
  5. 「机器学习」机器学习算法优缺点对比(汇总篇)
  6. 「SAP技术」SAP MM 委外加工采购流程里副产品的收货
  7. 知乎宣布完成4.34亿美元F轮融资,快手领投,融资额刷新此前记录
  8. 强化学习应用于组合优化问题
  9. 《用Python进行自然语言处理》第6章 学习分类文本
  10. torch.tensordot()介绍