免费注册 查看新帖 |

Chinaunix

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

[C] 请教C语言牛人----关于int与unsigned int的奇怪问题 [复制链接]

论坛徽章:
0
51 [报告]
发表于 2010-06-13 19:35 |只看该作者
不敢苟同.语言本身就是一个独立封闭的逻辑体系,不需要其他的知识
   当然,我不反对学习汇编,操作系统……,但那并不是语言的基础和前提
pmerofc 发表于 2010-06-13 06:43



    计算机语言绝大多数人都是拿到实际环境里用的,又不是拿来搞语言理论研究的,都要对应实际的平台,对应的机器码或字节码,需要解决与平台相关的各种问题。
当然,当语言律师,只解释条款可以把它当成封闭体系(编译器作者被无视),还可以只学不用。因为使用也不是学习的必要条件嘛,比如拿来写书(著名作家谭浩强教授是很好的例子)。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
52 [报告]
发表于 2010-06-13 20:01 |只看该作者
个人理解,软件还是要看时代背景的。

就int溢出引发trap这回事说起,可以想象某个遥远的年代,
硬件成本高昂,以至于少几十个门电路都值得期待,
于是硬件上有这种设计也不足奇怪。(我猜的)
但是放到现在社会,不可能有人敢这样设计硬件。
即使他想这样设计,也会被人当bug看待,又不全是用C语言的人。

再着,软件考虑兼容性也是有限度的。对于如此弱的平台,
你现在的软件,兼容一个假想敌,有必要吗?
连int溢出都不支持的chip, 还能不能有市场?想都不用想。

C标准固然要看,更要理解着看,它为什么要有这样的说法。
看完标准,得出的结论就是,完全不必再理会此条款。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
53 [报告]
发表于 2010-06-13 20:25 |只看该作者
回复 52# 群雄逐鹿中原

我的看法是: 不轻易违反标准, 除非有很好的理由。

举2个例子, 一个是逆向遍历数组, 一个是把指针当作数。


下面的写法指针会移动到数值合法范围之外, 属于未定义行为。

  1. T a[N];
  2. for (T* p=&a[N-1]; p>=a; --p )
  3.       visit(*p);
复制代码
不管未定义行为究竟会不会造成什么影响( 以前有个帖讨论过逆向遍历)。
将循环改写成如下形式也没什么不妥:

  1. for (T* p=&a[N]; p!=a; )
  2.       --p, visit(*p);
复制代码
这样就将指针控制在了合法的范围中, 也不产生多余的运算, 何乐而不为?


而另一方面, 指针和整数之间的转换, 最好情况下也是由实现定义的。
除非有绝对必要, 否则就不要做这种工作。
绝对必要的情况: 一些api要求这么做。
例如Windows, 就不说了, 到处都是将整数当作指针。
而posix中, 如mprotect, 是要求传递页对齐的地址。

如何将指针对齐到页边界? 我找过很多代码, 都是将指针当作数来处理。

而将指针当作数, 有些时候会获得很大的效率提升: 从对数到常数时间。
这也是不得不用的。不可移植就不可移植, 因为这实在太诱人了。
大不了对不可移植的机器重新写一份对数的算法。
也不能取它们的交集, 而只实现对数算法。

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
54 [报告]
发表于 2010-06-13 20:53 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
55 [报告]
发表于 2010-06-13 21:50 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
56 [报告]
发表于 2010-06-13 22:02 |只看该作者
本帖最后由 群雄逐鹿中原 于 2010-06-13 22:05 编辑
先(震惊的表情)

pmerofc 发表于 2010-06-13 21:50


别震惊,其实我也是标准拥护者。但世事无绝对,
做软件不就是各种取舍中找一条妥协之道吗?
何况不支持int溢出早已是历史,这个我想正常心智都应该能推断的。

再一个事实例证,如果放5年前写html,用w3c的标准,没人能写出好网页。

论坛徽章:
0
57 [报告]
发表于 2010-06-13 22:04 |只看该作者
回复 54# pmerofc


    如果某个项目只能用gcc,然后你发现gcc没有按标准实现某个细节,而这个细节你又绕不开的时候。你是通过套用标准来否定gcc并放弃该开发项目呢?还是通过编译结果的汇编代码了解其实现,通过宏选择编译器版本做出符合标准代码和目前gcc能使用的代码。你如果多读些源码,会发现跨平台的软件有很多这样的代码存在(编译器语法的,不同操作系统C库函数差异的,平台差异的),除了学会坚持,还得学会妥协。这是个现实的世界而不是理论的世界。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
58 [报告]
发表于 2010-06-13 22:10 |只看该作者
回复 53# OwnWaterloo


这句说的太好了,非常赞同:不轻易违反标准, 除非有很好的理由。
但不能理解pmerofc的那么绝对,要权衡利弊嘛

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
59 [报告]
发表于 2010-06-13 22:40 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
60 [报告]
发表于 2010-06-13 22:42 |只看该作者
本帖最后由 guoruimin 于 2010-06-13 23:07 编辑

像C/C++这种本身就和硬件比较接近的语言,是和汇编语言密不可分的。
能看懂汇编,不但能理解编译器实现的语言特征,更能有效的发现编译器的缺陷。
不了解寄存器、堆栈、内存寻址等,根本无法真正的理解C语言。
真正的C语言程序员,写代码的时候,就能考虑到汇编指令的生成,写出优化的代码。
如:
x = get_x();
y = get_y();
h += y;

y = get_y();
x = get_x();
h += y;

x = 3;
y *= x;

x = 3;
y += y << 1;

这些内容规范里根本不会讲,但如果真正了解C语言,就是可以写出更有效的代码。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP