免费注册 查看新帖 |

Chinaunix

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

[C] 有多少C程序员认为这是错误的写法 [复制链接]

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

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

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

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

论坛徽章:
0
45 [报告]
发表于 2012-05-11 23:33 |只看该作者
pmerofc 发表于 2012-05-11 23:12
回复 36# 变异老鼠


这个还真是对的。

C99 7.20.3/1
... The pointer returned if the allocation
succeeds is suitably aligned so that it may be assigned to a pointer to any type of object
and then used to access such an object or an array of such objects in the space allocated
(until the space is explicitly deallocated). ...

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

比如:

  1. /* C89 */
  2. typedef struct {
  3.       ...
  4.       char s[1];
  5. } T;

  6. size_t l = strlen(argv[0]);
  7. T* p = (T*)malloc( l + sizeof *p);
  8. strcpy(p->s, argv[0]);
  9. ...
复制代码
当然,这技巧是饱受争议的……

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

原文:
在实际中并不考虑这类少见的问题。我们不认为在任何编译器和机器上,对于小整数n, b=(b-n)+n 确实会失败。
即使在分段式机器中,发生了编译器存储了某些b-n的表达式(也许是违法规则的),那么,当表达式加上n后,b就恢复正常。
本书中的这些内存分配程序,从1988年第一版发表以后就已广泛应用,当然也存在着同样的问题。
但是我们从未收到过在这方面失败的报告,哪怕是一份简单的报告(尽管有许多读者指出在理论上它确实可能失败)。
我们也曾与C语言标准团体通信,希望在将来的标准中能够允许这个需要“b=(b-n)+n”(至少对n的某些范围,并设n为短型数据类型)。
因为这样做,看起来与现有的一些编译器并没有什么冲突。

《C数值算法》 B.1.2 单位偏移量

b在上下文中是指针类型。"短型数据类型"确实是译文原文…… 英文原文我也不知道是什么……


很少有non-trivial的程序可以用纯ISO C写成。
看trivial怎么定义吧,如果严格到cp都算是trivial的话,那基本可以说:non-trivial程序不可能由ISO C写成。
问题的关键不在于程序是否是100%纯ISC C,而是 1) 超出是否值得 2) 超出部分比重多大


陈同学的问题就是: 1) 为了一点莫须有的可读性而超出C范围 —— 我认为不值得  2) 这不是他的什么个人项目,而是传道授业的书,不应该这么乱来。
而数值算法为了下标问题超出C范围我认为也不值得, C程序员写C程序时就应该从0开始数数…… 而不是和语言对着干……
不过这书重点是算法而非C语言(第1版是Fortran,也许是固守1下标的理由之一……)。

论坛徽章:
0
48 [报告]
发表于 2012-05-12 00:12 |只看该作者
回复 39# pmerofc


   行指针也就是 在数组里那样通俗的叫法,其实就是一维数组指针

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

1下标在35楼就说了,它超出C的范围了,而且都能设想出一种可能性。记得以前有过p[-1]的帖子,这里就不重复了。


但其他两个(连续内存、首成员地址)要说超出C范围了吧,也许确实超了;但想不出会产生什么问题。
pmerofc 发表于 2012-05-11 23:21
回复 35# OwnWaterloo

C99和C11都特意指出了这是一种未定义行为(附录)
究竟是出于什么深刻的原因
我也不太明白

也许只是有罪推定呢? 制定标准时觉得这没用 —— 都给我用flexible去…… —— 但又是确实他们的失误呢?


为什么是失误?将malloc得到的内存当作二维又或是一维显然必须是对的……
那么问题就来了,就是35楼与36楼的。这问题还可以反问44楼的cfaq:为什么malloc就可以,而自动变量就不行?

比如44楼的cfaq的代码:

  1. f2(&array[0][0], NROWS, NCOLUMNS);
复制代码
如果改为:

  1. void* p = malloc(NROWS * NCOLUMNS* sizeof(int));
  2. f2(p, NROWS, NCOLUMNS);
复制代码
内存大小相同 —— sizeof(array)==NROWS * NCOLUMNS* sizeof(int) —— ,对齐都合乎要求, 就完全没问题。
为什么一个可以,另一个就不可以?

甚至依然用自动变量,但用一个union:

  1. union {
  2.       int a1[N*M];
  3.       int a2[N][M];
  4. } u;
复制代码
又该怎么解释?


能想到可能的回答是 —— 就像35楼说的 —— 编译器进行一些边界检查。对a[N],超出[(char*)a,(char*)a+sizeof a)就报错。
而对b[N][M],超出[(char*)b, (char*)b+sizeof b) 的访问报错我觉得可以做到。
但对中间的访问,编译器还能够区分出是通过二维还是一维访问,并且真的这么干了…… 那也管太宽了……
如果这编译器还不提供命令行选项去掉这种功能,至少这编译器我不会去用……

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
50 [报告]
发表于 2012-05-12 00:38 |只看该作者
回复 45# 变异老鼠

我回复错人了……  是准备回复pmerofc的……
你俩头像太一致了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP