C最大的错误

2021-06-20 23:12:55

C可以说是世界上最成功的编程语言。当然,它的成功有 无休止地诱惑人们改善它。因此,C可能是族长 最长的语言列表。值得注意的是C ++,D编程语言, 最近,最近。有无限的讨论线程如何修复c,继续 回到80年代。

所以这是一个很好的地面。什么可能被添加到这汤?我是 大多数此类讨论围绕细节。更有趣是什么 最大的基本错误。我们应该考虑到时代的背景 它产生的c,以及它试图解决的问题和环境 其中旨在使用它。请记住,它是为16岁开发的 位机器,具有极其有限的资源可用。 我想解雇这样的东西 做垃圾收集,功能编程,动态键入或OOP。那些没有问题c 试图解决,所以缺乏他们不是错误。

什么错误导致更多的悲伤,更多的错误,更多的解决方法,更无尽的时间 消耗等等,比任何其他人?很多人会说 null指针。 我不同意。

我不是指他们使用相同的语法或隐式转换 阵列指向指针。我的意思是无法将数组传递给函数 作为一个数组,即使它被声明为一个数组。 C将静静地转换 数组是指针,并将重写函数声明 所以它是一个指针:

这个看似无害的便利特征是无尽邪恶的根源。 这意味着一旦阵列离开定义的范围, 他们成为指针,并失去了赋予程度的信息 数组 - 数组维度。失去的后果是什么? 此信息?

必须使用替代方案。对于字符串,这是0终结者的一个原因。 为了 其他阵列,从上下文以编程方式推断出来。自然, 每种情况都不同,所以无休止的阵列(!)错误。

C字符串函数的星系,从不安全的strcpy()到Sprintf()向后, 是直接的结果。修复了这一点有各种各样的尝试,例如 安全C库。 然后有所有缓冲区溢出,因为函数 递给了一个指针没有 想法,限制是什么,并且没有阵列界限检查。

C ++在TOTO中继承了这个问题,从而产生了10年以上的产卵 尝试创建可用的字符串类。即使是最终的std :: string结果 它需要妥协,它需要与C 0终止字符串兼容。 C ++通过发明STD :: Vector,以及 许多编程指南使用T []样式阵列避开。但遗产 C阵列继续在C ++中 不安全的迭代器设计。

C99试图解决这个问题,但它仍然存在致命的错误 不将数组维度与数组指向指针组合成一个类型。

但一切都没有丢失。 C仍然可以修复。所有它需要的是一点新语法:

意味着数组被传递为所谓的“胖指针”,即由一个组成 指向阵列的开始,以及数组维度的size_t。 当然,这不会修复任何现有代码,但它将启用要编写的新代码 正确又强大。随着时间的推移,语法:

可以通过惯例和编译者弃用。甚至更好,过渡到 可以通过使与旧代码兼容的声明兼容的声明:

#if newc. extern void foo(char a [..]); #elif c99 extern void foo(size_t com,char a [dim]); #别的 extern void foo(size_t dim,char * a); #万一

这种变化不会以所有闪亮的方式将c转化为现代语言 钟声和口哨。它仍然是C,精神和练习。它会 只需减轻C程序员处理一个特殊的常量,有害的来源 虫子。

来自K + R的相关文本C编程语言5.3是 “当数组名称传递给函数时,通过了什么是 阵列开头的位置。 在被叫功能中, 这个参数是一个变量,就像任何其他变量一样,所以 数组名称参数是真正的指针,即包含包含的变量 一个地址。” 来自C 99标准的相关文本6.7.5.3.7是 “将参数声明为”类型“ 应调整为“合格指针” “ 来自Stroupstrup的C ++编程语言第一版7.1 “像往常一样,数组名称被转换为指针。”