免费注册 查看新帖 |

Chinaunix

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

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

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
11 [报告]
发表于 2011-10-17 17:06 |只看该作者
回复 10# egmkang

总觉得weibo太浮躁了……  灌灌水可以,想要严肃讨论个什么还真没那气氛……
是我的错觉/偏见吗?

论坛徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技术图书徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44双子座
日期:2013-12-27 12:32:29双子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
12 [报告]
发表于 2011-10-17 17:08 |只看该作者
回复 8# OwnWaterloo

请教下,记得哪里曾看到过新标准对多线程编程做了很多支持吧,好象以后有语言内置的原子类型了?

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
13 [报告]
发表于 2011-10-17 17:14 |只看该作者
回复 12# asuka2001

C++11也才发布不久……   在这之前,各种细节是改来改去改来改去……
所以详细细节我也不清楚……  原子操作标准化貌似有听说过,是否最终被敲定就不知道了……

感兴趣就下个ISO文档呗……
链接可以问问谷娘…… 她也许知道……
对C++11始终缺乏动力的说……

论坛徽章:
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
14 [报告]
发表于 2011-10-17 17:18 |只看该作者
回复  zylthinking

序列点、副作用以及它们与优化之间的关系可能C标准里找得到 —— 这是想请教他们的地 ...
OwnWaterloo 发表于 2011-10-17 16:58


没想挑战C标准, 只是某人将编程相关的东西一律归结为C标准, 只要通宵了C标准, 妈的上天当玉帝, 下地当阎王, 无所不能无所不包。
凭几寸不烂之舌嘲笑问堆栈问题的, 斤斤计较 “全局变量” 而不叫 “外部变量” 是犯了弥天大错的, 说 C标准规定了机器通性的; 抓住潭浩强语法问题, 一天不骂不舒服的。
说实在的, 能背标准背那么熟, 我还有些佩服呢, 我根本没看过; 看过的自然比没看过要好些;
问题是此人拿住这玩意任意夸大, 丝毫不顾现实情况, 就算使用了 99% 的编译器都会 follow 的特性, 只要不在C标准中, 准是一副你错了, 和老谭一模一样的论调。

还有一帮人崇拜他, 大概都想着把C标准每个标点符号都背过, 就是牛人了。。。。

论坛徽章:
0
15 [报告]
发表于 2011-10-17 21:09 |只看该作者
本帖最后由 davelv 于 2011-10-17 21:54 编辑

回复 8# OwnWaterloo
  难得OwnWaterloo老兄想起了在下,以及最近我也看到了一些并行方面的贴,就浮上水面说说自己的见解吧。
  C语言是典型的Von Neumann体系下的编译语言:"存储程序并顺序执行"。
  70年代初的时候C语言发明和Unix的产生是息息相关的,必须要在一起说明的。当是计算机并行运算并不是很普遍,绝大多数的并行是靠多进程完全任务的,线程还没有被广泛提及,CPU也没有乱序执行的概念。这时候进程间的并行就靠操作系统去隔离,这一点当是的Unix做的非常不错,并由于涉及到Unix设计哲学(简单即美)复杂而高效的多线程在Unix类系统上一直没有得到重视,这也是影响了C语言的产生和发展。C语言设计者也认为C语言应该足够小巧灵活(C语言以控制和处理内部(存)数据为优先任务,个人见解),不要引入太多平台差异的东西,于是I/O功能和后来突飞猛进的并行计算自然只能丢到库中或者干脆完全隔离不予考虑。
  计算模型中的多进程内存屏障靠OS就可以,主要就是一些进程通知和I/O共享的问题,得益于CPU对多任务的支持和I/O本身的串行性和独立性等,这些并不是很难解决。但并不是所有的并行问题完全可以靠OS来完成。多进程读写共享文件,这种情况在70年代的时候也没有现成的函数使用(现在有文件锁这种东西),只能自己用OS提供的信号机制而自己设计模型。不过由于这样的问题已经比较依赖业务逻辑,所以交给程序员自己去处理也是符合C语言和OS的设计特性,而且Unix也做了很多细节屏蔽,对程序员是足够友好了。这里典型OS代表是1976年的Unix 6th(这是从贝尔实验室流出并广泛使用的Unix版本)。
  多进程间用I/O和信号去传送数据有时候不能满足需求,于是Unix又引入了共享存储和消息队列的概念和相关操作。但这也增加了操作复杂性,共享存储的互斥需要程序员手工去完成(一般是和I/O互斥一样用信号通信),而且虽然一次传送的数据多了,过于频繁的互斥操作仍受到信号机制的限制。典型OS代表是1983由AT&T于年开始发行的System V系列版本。
  然而随着计算机科学发展,计算机所处理的任务复杂度也是越来越高,这也必然要求软件设计的复杂度增高。多进程看起来不能满足所有的并行问题,于是多线程概念被提及和重视起来。这样就引来的新的复杂机制,就是进程内的共享问题。C语言仍遵循着设计理念,这些交给程序员和OS处理,语言本身不参与处理这些问题。于是Unix又修改了信号和进程部分等,加入了线程模型。由于进程内部出现了临界区,以及线程和信号的相互作用,使得并行计算模型大幅度复杂化。而且由于Unix世界的两次大战,各个分裂的众支持者们对多线程的模型理解不一,使的各个版本多线程差异很大,直到1995年POSIX 1.c标准引入了线程模型才有一个统一的标准。前几天在群里看了一个图片。从单进程,到多进程协作,再到多线程,熟练掌握这些技术的程序员数量急剧递减,也说明了一个问题?我们的计算模型是不是太复杂了?
  上面谈论基本上是OS和并行模型的问题,内容似乎太多了。下面再说下CPU的问题。CPU的并行计算模型也是和OS一样进化的,也是有了CPU支持OS才能更好的处理这些问题。多进程和多线程的支持不再细说,就说咱们议论的重点,乱序执行。乱序执行的概念早在上世纪60年代提出来的,但是直到90年代初IBM才制造出实用的微处理器POWER1,然后后来的intel,sun各家也开始使用这项技术用于CPU制造以及编译器优化,到现在也不过20年和多线程技术的实用年份差不多。总体来说这并不像多进程和多线程一样是架构上的并行技术,而是一种局部优化技术。连多进程和多线程都没有对C语言本身产生明显影响,自然乱序执行也不会有这么大能力。
  不过一个事物既然产生了,它的影响还是有的,虽然它仍然在宏观上维持着Von Neumann的计算体系,但在微观上却背离了。拿编译器为例,有些指令或者语句会被优化成更高效率的序列,当然前提是在不影响程序执行的情况下。如果影响了程序的行为,那么我们可以说这是编译器的一个BUG。关于这点问题zylthinking网友在帖子《为什么用户空间程序不用考虑内存屏障?》http://bbs.chinaunix.net/thread-3607285-1-1.html提到了,我的回答也是显然易见的,看语言规定的计算模型而论。C语言自然规定了语句的顺序执行,所以编译器也得按照顺序执行的行为来处理,如果有任何乱序影响了最终结果,那么负责任的应该是编译器,而不是使用编译器的程序员(谁来负责这只是理想的说法)。但是可不可以发明一种在计算模型上就支持乱序执行的语言呢?我目前的答案是否定的,因为程序设计语言的计算模型本来就是把细节抽象掉,更多去关注高级逻辑。对于这样一种宏观和微观不一致的优化手段,我们没有必要花费太大的功夫在它身上,这是得不偿失的,用不同的抽象层次去屏蔽这些不一致即可。这样只需要编译器和CPU设计者对乱序执行进行良好的处理,就可以保证绝大多数开发者在不知情的情况下达到程序加速的目的。
  虽然乱序执行这种技术不能从根本上撼动我们传统的计算模型,但它是一个种子,联合起来起多进程和多线程的概念,以及以后出现的并行计算技术会不会导致我们产生颠覆性的计算模型和计算语言呢?这点还是要归到抽象层次上。因为计算机是为人类服务的,而人能驾驭的复杂度是有限的。就像计算机和计算机网络的产生和发展改变了人类信息存储,处理和交流的方式。但是人类不会用C语言去进行日常交流,C语言只是给程序员用的,程序员也不用完全掌握电子信号怎么在网络间传播也可以写出正确的通信程序。同理以后会有更多更新的计算技术。但是这些计算技术的细节会被层层分解和屏蔽,使得人类可以在自己能掌握的复杂度内解决问题。首先界定问题,才能处理问题。但是整体问题还是会变得复杂,你若想深入了解问题,自然要学习的东西会更多。
  说了这么多东西,其实都是行而上泛泛之论,没有说到具体细节。至于C语言标准有没有规定前一个语句必须在后一个语句之前完成?这个问题,答案自然就是肯定的了。

论坛徽章:
0
16 [报告]
发表于 2011-10-17 22:28 |只看该作者
现行正式ISO C不考虑线程。C1X在单线程保证sequence point前后的表达式的计算和副作用发生的顺序。
ISO C N1539
5.1.2.3 Program execution
1 The semantic descriptions in this International Standard describe the behavior of an abstract machine in which issues of optimization are irrelevant.
2 Accessing a volatile object, modifying an object, modifying a file, or calling a function that does any of those operations are all side effects,12) which are changes in the state of the execution environment. Evaluation of an expression in general includes both value computations and initiation of side effects. Value computation for an lvalue expression includes determining the identity of the designated object.
3 Sequenced before is an asymmetric, transitive, pair-wise relation between evaluations executed by a single thread, which induces a partial order among those evaluations. Given any two evaluations A and B, if A is sequenced before B, then the execution of A shall precede the execution of B. (Conversely, if A is sequenced before B, then B is sequenced after A.) If A is not sequenced before or after B, then A and B are unsequenced. Evaluations A and B are indeterminately sequenced when A is sequenced either before or after B, but it is unspecified which.13) The presence of a sequence point between the evaluation of expressions A and B implies that every value computation and side effect associated with A is sequenced before every value computation and side effect associated with B. (A summary of the sequence points is given in annex C.)
...

论坛徽章:
0
17 [报告]
发表于 2011-10-17 22:37 |只看该作者
现行正式ISO C不考虑线程。C1X在单线程保证sequence point前后的表达式的计算和副作用发生的顺序。
ISO C  ...
幻の上帝 发表于 2011-10-17 22:28


有几个要注意的地方:
1.这几段描述C的语义如何被实现以及定义什么是C程序的行为。涉及整个程序,即使是单独的陈述比起shall和constraints也有更强的效力。对此的违例直接导致程序不是ISO C定义的C程序,无所谓undefined behavior(本身就是在详细描述哪些需要被当作是(observable)behavior……= =)。
2.条款1的in which issues of optimization are irrelevant应该指abstract machine,无关actual implementation,即使被优化也需要遵守这里的规则。
3.之后有:
8 More stringent correspondences between abstract and actual semantics may be defined by each implementation.
可知这里的行为蕴含的abstract semantics和actual semantics需要一致。

论坛徽章:
0
18 [报告]
发表于 2011-10-17 22:40 |只看该作者
回复  egmkang

总觉得weibo太浮躁了……  灌灌水可以,想要严肃讨论个什么还真没那气氛……
是我的错觉 ...
OwnWaterloo 发表于 2011-10-17 17:06


百度贴吧 也有  @功能了...
Discuz论坛加个@功能应该也很简单的吧.

论坛徽章:
0
19 [报告]
发表于 2011-10-18 07:04 |只看该作者
回复 16# 幻の上帝
啊哦,C1x的草稿都找出来了。

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
20 [报告]
发表于 2011-10-18 08:11 |只看该作者
有 序列点 一说,但在这里对你不起作用,呵呵
只要最终“可观察”结果不违背任何条款就行。

比如
i = 0;
i = 1;
可能优化成
i = 1;
因为,无论编译器有没有做i = 0;,你都无法察觉到,所以编译器就可做,也可以不做。

同样,前一个语句在后一个语句之后完成 只要和  前一个语句在前一个语句之前完成 的最终可观察结果一致,那么编译器这么做就是符合标准的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP