在编译的编程语言(如C)和解释的语言(如MATLAB)中访问越界(负或不可访问)索引有什么区别?
根据这个网站的建议,我研究了许多关于访问越界索引的线程。然而,这些线程中的大多数只关注于解决源代码的问题。也就是说,我从这个网站上了解到,在使用C时访问越界索引会导致未定义的行为。通过使用MATLAB进行实验,我猜解释语言会进行测试,以确定索引是否应该不可访问,并在访问越界索引之前"捕获"写得不好的代码。一般来说,解释语言确实是这样吗?或者,它们类似于C(编译)语言,会导致某种程度的未定义行为发生吗?在任何编译语言的程序中访问越界索引是否会导致未定义的行为?
一些语言将其作为实现的"细节",而另一些语言则明确指定了预期的行为。。。但随着时间的推移,这种情况在几种编程语言中都发生了变化。
关于C,在数组中使用负索引是完全合法的(也是有用的),即使这有时可能导致崩溃或代码/数据损坏(无论是否有意),因为C尽量不限制您作为程序员的能力。如果你知道C语言是如何实现的,那么对于基于堆栈或基于malloc的错误寻址内存块会发生什么就没有那么多的不确定性了。C编译器可能会在编译过程中发出警告,以帮助防止出现错误(无意义的负数组索引)。
其他语言由程序员决定并试图阻止这些操作,无论是在编译时(PASCAL是一个很好的老例子)还是在执行时(JIT、VM等)。除非语言规范定义了特定的行为,否则没有通用规则。
即使在C中,也可以使用许多方法来防止意外损坏,例如围绕阵列内存块的guardian memory areas
。然后可以通过信号处理程序处理故障。
由于大多数其他语言都依赖于C/C++实现,这也是"更现代"的编程语言在规范或实现中处理这些问题(负数组索引)的方式。也可以使用对负数组索引的测试,但会降低性能。
C#或Java变量比C中占用更多的空间,因为它们分配了更多的信息(锁、垃圾收集、保护区等),而C变量浪费的空间可能只会在程序员没有用更复杂的东西取代默认行为时产生。