@FrankHB 不是科班的,我表达的”优化“指的是“不需要你自己完成,编译器完成的",表达有误,见谅。 我们讨论的问题不是理解指针吗? Sum Type 是在看 Haskell 时了解的,谢谢让我了解了 C 实现的 tagged union ,但是这个实现难道不需要理解指针?所以到底应该怎么理解指针?别说指针是语言设计的错误。
x8
2016 年 8 月 19 日
@muziki 嗯,了解。 我的意思是:初学者只需要把 C 语言当成一个纯粹的工具,了解底层,做实验的工具,并没有上升到语言本身的问题上,我其实也不关心 C 语言语义上的东西。作为初学者了解底层的起手工具, C 语言最合适。 带偏是难免的,任何资料都可能存在误导,遇到问题了,初学者自己要学会查问题,做实验,和别人交流,验证想法。 我希望初学者通过学习 C 语言,通过遇到问题解决问题,学到其他更有用的东西,比如“底层封装得并不完美”,“编译器并不能保证程序的正确性”,永远保持向下探究的态度,顺带还有一大票的底层知识,而不单单只是学一门程序语言的语法语义。
@proudzhu 你的误解应该综合来源于几个方面。 须知: 1.底层( ISA 设计提供的)的指针,一般就是有特别含义的地址。 2.C 所谓的指针和上面所谓的指针根本不是一回事。 3.这两者在实现上是有些关系,但不需要倒腾二进制互操作的用户(显然包括绝大多数新手),附会只是添乱。 4.大部分用户没有机会也不必要同时接受把这些东西理解得面面俱到的系统训练。 只有绝对少数领域(像实现 CPU 的、做编译器的、维护系统 ABI 的、在这个层次以下逆向的、因为目前 ISA 抽象混乱做 OS 不得不在这个层次上 hack 的……)的实现者和设计人员中的 architect 才有必要把这些都理解清楚。 相对来讲,只学高级语言,忘记“指针就是地址”符合更一般语言用户的需求。 先钦定指针=地址,根本就是搞错问题领域了。我当作误导,不算冤枉吧?
@proudzhu 很遗憾,我还真找不出“不是错误”的借口。这是让实现细节倒置到接口之上的典型 leady abstraction ,怎么看都是设计上的经典反面教材,只是各种不明真相的群众以讹传讹说成了“精华”,也是无语。 改正这个问题最简单的做法就是直接提供底层的指针代替现在的指针,可以实现为整数或者加上一些检查的地址类型(也可以考虑提供地址偏移量类型),于是“(对象)指针就是(可选的)地址”成了真命题,符合一些用户的预期。而现在 C 那种指针应该被废弃,非要兼容也应该弱化为库来提供而不是语言内建。这样语言规范里的废话也能转移出去一大坨,二进制兼容性维护起来也方便得多。 然而很遗憾, C 在参数化类型上的开洞导致这种改动必须另加很基本的核心语言特性而不现实(不像 C++有模板加上一个扩展标识符占位就立刻能凑数)。所以估计接下来几十年将错就错还是主流了。
proudzhu
2016 年 8 月 19 日
@FrankHB 如果我记得没错的话,程序都是访问的是虚拟地址空间,和真实硬件的地址是映射关系,我们说的 C 里的指针是指向这些虚拟地址空间的。 我当然知道高级语言的用户不需要了解这些,但是我们现在讨论的不就是怎么理解指针吗? 还是认为指针=地址,搞 DSP 的时候也和这个理解一致,求科班人士拍醒。
FrankHB
2016 年 8 月 19 日
@proudzhu 你要知道 C 这种人为设计的东西,通过对“指针”这个术语的明确的定义和拒绝提及其它义项,就完美地把“指针”在其它领域的本义覆盖掉了。所以光是讨论 C ,你只有一个无歧义的“指针”的概念。如果你需要同时讨论更底层的某些 ISA 中定义的指针,那还不如直接说“地址”更清楚,不需要无谓增加同义词和混乱。(你也不方便随便发明一个新概念代替 C 所谓的“指针”了,加上“智能指针”这类派生,“指针”这个词在一般场合是保留给高级语言的。)
而虚拟地址空间是另外一层抽象,通常比 C 实现的层次更低。不算 WG14 某些扩展提案, C 本身不对地址空间做任何抽象(其实根本就没提什么地址空间), ISA 和一些硬件 spec 倒是会提到支持,所以提虚拟地址空间实际上已经是 C 以下的底层话题了。排除高级语言这个意义上讨论“指针”的含义反倒比上面明确,虽然我仍然更愿意看到“地址”这样无歧义的表述。(嘛,严格来说上面所有的地址特指 memory byte address ,不过一般人也不会没事倒腾寄存器编址什么的……)