免费注册 查看新帖 |

Chinaunix

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

[C] 初中级C语言水平自测:srand((int)time(0)); 有没有错? [复制链接]

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

避免所有undefined behavior?

要避免所有undefined behavior并不容易。。。


@starwing83,既然Lua的邮件列表里提到了,我在想是不是因为Lua源代码里已经这么写了。。。
存在lua number -> c integral, 并且没有检查范围。

我估计很多需要大量处理浮点数的库,也不会对每一个long double -> double, double -> float 都进行检查。

并且。。。  请各位摸着良心说。。。  自己写的代码里有没有这样的情况:
1. 有符号数相加(或相乘!)
2. 相加前没有检测
3. 也没有去证明加法的结果一定没有超出该有符号数的表示范围


这也是undefined behavior:
C99 6.5 Expressions

5 If an exceptional condition occurs during the evaluation of an expression
(that is, if the result is not mathematically defined or not in the range of representable values for its type),
the behavior is undefined.

C89 6.3 EXPRESSIONS
...
If an exception occurs during the evaluation of an expression
(that is, if the result is not mathematically defined or not representable),
the behavior is undefined.
...


然后,在知道这是undefined behavior的情况下,不能再以无知者无罪为借口的情况下,会去将代码里的每一处有符号数加法都:
1. 证明它一定不会溢出
2. 或者在相加前检测
吗? 对检测失败的情况又该怎么处理?


我感觉这代价就太大了一些。。。  会开始考虑换 i) 有异常处理的 ii) 可以重载 + 的 语言了。。。
除0(mathematically defined)我想一般都会处理,因为一般都会立即产生错误。。。



回到srand(time(0))。不知道具体implementation的情况下, time_t有可能是浮点数, 也就有可能产生undefined behavior。
但如果一定要避免, 该怎么做?

  1. time_t t = time(0);
  2. if ( 0 <= t && t <= UINT_MAX ) srand(t);
  3. else { /* 该怎么办。。。 */ }
复制代码

  1. srand( fmod( fabs(time(0)) , UINT_MAX - 1 ) );
复制代码
不如前面那个罗嗦, 但依然很罗嗦。。。 而且不一定就没有问题。。。 (要是UINT_MAX-1 比 DBL_MAX 大该怎么办。。。 有这种可能性么?)


并且还得分两种情况: i) 这是实际代码,需要很好的正确性的保障(但这种情况srand/rand合适么?) ii) 这是教学代码并且主要目的、重点根本就不在srand/rand上。。。
如果这样写, 初学者看到了就不会对此有疑问?

@pmerofc,就类似 char const* , 严格的说应该这么写。
但有时候代码的重点不在这里, 需要避免一下子给初学者抛出太多的信息, 而是应该各个击破, 于是可能就先选择 char* 了。
你也理解的对吧?

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

但C语言并没有说scran rate为0是undefined behavior。
嗯,其实C语言里根本就不会有scran rate这个概念。。。


就是说,这个例子并没有说明是C语言里的undefined behavior(floating->integral超出范围、或者其他)造成硬件损坏的。
假设scran rate是一个特殊的内存地址,并且是算术类型。设置它的值为0在C语言里是正确的行为。
是这个硬件的spec不允许而造成的损坏。


不知道原文是什么。。。 也有可能是翻译出的问题。。。

论坛徽章:
0
33 [报告]
发表于 2012-09-27 16:42 |只看该作者
回复 7# zylthinking


void srand(unsigned int seed);

这样会误导人吧。。。

传入参数是什么类型,由函数形参列表决定(窄转宽,或等宽转等宽),你传int后,它还是按照unisgned int “解读”。。。

论坛徽章:
0
34 [报告]
发表于 2012-09-27 17:19 |只看该作者
回复 32# OwnWaterloo


    scran rate就是那什么什么扫描速率,

原文大概是这个,

http://books.google.co.jp/books? ... eltdown&f=false

我反复看都觉得这不象是某某已发事故,只是为了证明有这可能,“不是那么牵强”。
不是UB,我手滑把这东西设成0也会导致烧坏的..

论坛徽章:
0
35 [报告]
发表于 2012-09-27 17:40 |只看该作者
这种用法真的很让人担忧,当初阿丽亚娜5升空后爆炸,其中一个导致发射失败的可能原因就是:64位的浮点数转为16位整型造成溢出。为此在C语言的安全规范中特别列出了这个问题。希望朋友们在实际工作中要特别小心这个问题。
阿丽亚娜5事故调查报告原文:The internal SRI software exception was caused during execution of a data conversion from 64-bit floating point to 16-bit signed integer value. The floating point number which was converted had a value greater than what could be represented by a 16-bit signed integer. This resulted in an Operand Error. The data conversion instructions (in Ada code) were not protected from causing an Operand Error, although other conversions of comparable variables in the same place in the code were protected.

论坛徽章:
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
36 [报告]
发表于 2012-09-27 17:45 |只看该作者
isaacxu 发表于 2012-09-27 17:40
这种用法真的很让人担忧,当初阿丽亚娜5升空后爆炸,其中一个导致发射失败的可能原因就是:64位的浮点数转为 ...


要看具体情景, 你说的这个肯定是个  bug 无疑, 陈小三的交通灯例子里就不是。
不结合具体情况, 生搬教条, 做的再精确, 也失去了人的灵动, 干脆将大脑换成CPU好了, 也好让我尝试写个程序, 让他给我家打扫厕所

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

Great!

我勤快,弄个排字版:
Undefined Behavior Causes CPU Meltdown in IBM PC's!

The suggestion of undefined software behavior causing CPU meltdown isn't as farfetched as it first appears.
The original IBM PC monitor operated at a horizontal scan rate provided by the video controller chip. The flyback transformer (the gadget that produces the high voltage needed to accelerate the electrons to light up the phosphors on the monitor) relied on this being a reasonable frequency.
However, it was possible, in software, to set the video chip scan rate to zero, thus feeding a constant voltage into the primary side of the transformer. It then acted as a resistor, and dissipated its power as heat rather than transforming it up onto the screen. This burned the monitor out in seconds. Voilà: undefined software behavior causes system meltdown!


呃,观点还是前面的:
1. 这其实是在说"undefined software behavior", 以及与C语言的undefined behavior无关了
2. "set the video chip scan rate to zero" 的行为是良好定义的, 肯定能把它设置为0, 否则就不会烧毁了。
这段文字前面还有一段话:
since the behavior is undefined, the compiler is free to do anything and doesn't even have to warn you about it!

但设置为0, 编译器是必须老老实实做这件事的。


总之,C语言的undefined behavior引起严重事故的可能性不能说绝对没有。
但IBM的这个不能作为论据,它不是C语言的undefined behavior引起的,而且正是因为C语言是规规矩矩听了程序员的话、做了该做的事才会被烧毁的。。。

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

这个才有点C语言的undefined behavior引起事故的赶脚。。。

论坛徽章:
0
39 [报告]
发表于 2012-09-27 18:39 |只看该作者
回复 31# OwnWaterloo


    是的,这种溢出导致的UB,一定要避免,代码估计会搞得特别恶心。
我想起了java里没有unsigned类型,然后,某次要搞一堆的位运算,恶心死了。。。。

论坛徽章:
3
15-16赛季CBA联赛之山东
日期:2016-10-30 08:47:3015-16赛季CBA联赛之佛山
日期:2016-12-17 00:06:31CU十四周年纪念徽章
日期:2017-12-03 01:04:02
40 [报告]
发表于 2012-09-27 18:40 |只看该作者
回复 37# OwnWaterloo


    速度来路过歪楼 顺便学习了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP