免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: smalloc
打印 上一主题 下一主题

C语言标准有没有规定前一个语句必须在后一个语句之前完成? [复制链接]

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
31 [报告]
发表于 2011-10-18 15:14 |只看该作者
行规
cjaizss 发表于 2011-10-18 15:12


这个。。。。。。。。算了, 你不说出技术原因, 拿行规出来, 我再说话, 是不是要家法从事啊?

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
32 [报告]
发表于 2011-10-18 15:16 |只看该作者
本帖最后由 cjaizss 于 2011-10-18 15:19 编辑
这个。。。。。。。。算了, 你不说出技术原因, 拿行规出来, 我再说话, 是不是要家法从事啊?
zylthinking 发表于 2011-10-18 15:14



    那我就说一下吧,当你加了volatile这样的标志,编译器不再把它当可随意存储的内存看待,必须从真实地址去读,并且不得改变读写顺序.
    说白了,这就是对编译器的约束

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
33 [报告]
发表于 2011-10-18 15:27 |只看该作者
本帖最后由 zylthinking 于 2011-10-18 15:30 编辑
那我就说一下吧,当你加了volatile这样的标志,编译器不再把它当可随意存储的内存看待,必须从真实地 ...
cjaizss 发表于 2011-10-18 15:16



查了篇资料, 如果他是对的, 说明是你错了。。。。。。http://www.docin.com/p-204077894.html, 他妈的 macosx 不知道怎么截图

说白了,这就是对编译器的约束

唉, 其实我用不着查资料的, 就凭这一句, 就知道如果你说对了, 也就能证明你说错了

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
34 [报告]
发表于 2011-10-18 15:44 |只看该作者
那我就说一下吧,当你加了volatile这样的标志,编译器不再把它当可随意存储的内存看待,必须从真实地址去读,并且不得改变读写顺序.
说白了,这就是对编译器的约束
cjaizss 发表于 2011-10-18 15:16


你俩对话真搞笑……

我也倾向于volatile也不行,但拿不出确实的证据。

我的理解是volatile只适合这种:

  1. int volatile* reg = (int*)0x?????;
  2. while (*reg);
复制代码
就是说:
1. volatile向编译器表达的是: 程序状态会被程序执行之外的因素改变
2. 而非volatile向编译器说明:只会由程序执行改变。
3. volatile可以保证能观察到程序执行(主线程)之外产生的改动
但这里需要得到的保证是: enable与buffer之间改动的顺序,而非改动本身。


再没有得到volatile同时可以保证顺序的可靠证明(或证伪)前,我自己还是老老实实写个barrier吧……
大不了就是效率低点,但保证不错啊……


另外,一些不足以作证明的论据:
1. C/C++标准都是描述单线程行为的, volatile依然是在单线程下定义的, 没有过多考虑多线程的事
2. 所以C++11才会搞出很大的举动,想将内存模型标准化 —— 因为(相关文章很多)现有C/C++想编写正确的多线程程序很困难
3. volatile在msvc的各个版本之间定义不同
记得是vc8(vs2005)时改为volatile的写入会产生一个full barrier,这就可以保证顺序性。
也就是说,存在其他编译器(比如vc8之前)volatile是不会产生barrier,是不保证顺序性的。

论坛徽章:
0
35 [报告]
发表于 2011-10-18 15:45 |只看该作者
以下是多个编译器的实作结果:

1. 优化情况下,优化的结果,
   会违背楼主提到的 “顺序保证”。

2. 优化情况下,只保证在单线程的情况下,最终结果是正确的。

3. 加volatile,阻止优化,可提供用户程序级的“顺序保证”。

以下是本人想法:
1. 内核级的“顺序保证”,是操作系统和CPU的事情,
   如果要用户程序来管,只能说,这个系统太逊了!

2. 只有很少数时候,需要操作系统提供“顺序保证”,
   例如从介质装入可执行代码后,操作过cache后等。
   大多数的场合,顺序保证应该有CPU内部实现。
   如果连线程/进程切换这种频繁的场合,CPU都不能提供“顺序保证”的话,
   只能说,这个CPU太逊了。

论坛徽章:
0
36 [报告]
发表于 2011-10-18 15:49 |只看该作者
mutex_lock();
mutex_unlock();

两句话,能否有顺序保证?

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
37 [报告]
发表于 2011-10-18 15:50 |只看该作者
以下是多个编译器的实作结果:

1. 优化情况下,优化的结果,
   会违背楼主提到的 “顺序保证”。

2 ...
AD8018 发表于 2011-10-18 15:45



1 句话把现代多核CPU 骂死了大半, 多核cpu在操作系统底下做文章, 操作系统被骂又何辜。。。。。。

论坛徽章:
2
CU十二周年纪念徽章
日期:2013-10-24 15:41:34处女座
日期:2013-12-27 22:22:41
38 [报告]
发表于 2011-10-18 15:50 |只看该作者
我觉得用独立性解释很好啊。

ptr->buffrt = malloc(xxx);
ptr->enable = true;

两句话都有副作用,当副作用相互影响了,sense of time才变的重要。但这两句话产生的副作用没有关联性,互不影响,仅针对这两句局部来说,可以认为没有副作用,两句话甚至可以并发执行。程序员以书写顺序表达了自己期待的語句执行顺序,编译器或者CPU则以因副作用产生的关联性而产生的顺序为程序员之究极意图,后者可以通过前者推理出来。

归根结底,顺序(谁先谁后)暗示了时间,时间的概念(大部分时候)又因副作用而起。编译器或者CPU关注由副作用产生时间感知而确定的顺序,程序员看到(写下)的却是书写顺序。程序员对时间的概念与CPU编译器对时间的概念不在一级别:程序员的视角狭隘了。或者说用C语言无法表达细粒度(编译器CPU眼中)的顺序?还是人的逻辑(对时间的感知)根本就与编译器CPU合不到一块?  

(如果是纯粹函数式语言,没有副作用,所有語句都可以并发执行?)

论坛徽章:
0
39 [报告]
发表于 2011-10-18 15:59 |只看该作者
本帖最后由 狗蛋 于 2011-10-18 16:01 编辑

回复 38# tempname2

这个理解是正确的。

    volatile这个关键字说明的,就是“某个变量可能被其它线程读写或其它不可知的东西读写”这种情况。

编译器的职责,就是使得“这个变量被其它线程读写及其它不可知的读写过程”产生的任何side effect和优化前一致。

如果产生了不一致,就说明优化错了。


——所以说c/c++标准委员会是很奸诈的。他们只管最终结果,不管实现过程。他们说了volatile修饰的变量不得优化,你优化了没关系,但如果被人以任何合理方式抓到,就是你的错

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
40 [报告]
发表于 2011-10-18 16:00 |只看该作者
在不同表达式内的多个 volatile 变量间的操作顺序不会被优化器调换(即:编译器保证多个 volatile 变量在 sequence point 之间的访问顺序不会被优化和调整)。

这句话没理解透, 到底是再说两个变量如果都是 voatile, 则编译器保证不调整代码顺序呢, 还是说只要有一个是 volatile, 就能保证呢?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP