许多不好的事情发生了,并继续发生(或不,谁知道,任何事情都可能发生),因为没有明确的行为。我了解到,引入这一技术是为了给编译器提供一些优化空间,也许还可以使C++更容易移植到不同的平台和体系结构。然而,由未定义的行为引起的问题似乎太大,无法用这些论点来证明。对于未定义行为的其他参数是什么?如果没有,为什么仍然存在未定义的行为?
编辑为我的问题添加一些动机:由于几次与较少的C++狡猾的同事的坏经验,我已经习惯了使我的代码尽可能安全。坚持每一个论点,严谨的,正确的,诸如此类的东西。我试着留下尽可能少的空间来错误地使用我的代码,因为经验表明,如果有漏洞,人们会使用它们,然后他们会打电话给我,说我的代码很糟糕。我认为使我的代码尽可能安全是一个很好的实践。这就是为什么我不明白为什么存在未定义的行为。有人能不能给我一个未定义行为的例子,这些行为在运行时或编译时是无法检测到的,而且没有相当大的开销?
发布于 2010-05-05 09:51:16
我认为关注的核心来自于C/C++的速度哲学。
这些语言是在原始电源稀少的时候创建的,您需要进行所有的优化,这样就可以得到一些有用的东西。
指定如何处理UB意味着首先检测它,然后当然指定正确的处理。然而,发现它是违背了速度第一的语言哲学!
今天,我们还需要快速程序吗?是的,对于那些使用非常有限的资源(嵌入式系统)或非常严格的限制(响应时间或每秒事务)的人来说,我们确实需要尽可能地挤出时间。
我知道这句格言是用更多的硬件解决问题的。我们有一份我工作的申请:
它运行在大约40个怪物:8双核opteron (2800 RAM )与32 on的RAM。在这一点上,用更多的硬件来“更快”变得很困难,所以我们需要优化的代码,以及一种允许它的语言(我们确实限制了将汇编代码放入其中)。
我必须说我不太关心UB。如果您的程序调用UB,那么它需要修复任何实际发生的行为。当然,如果立即报告它们,那么修复它们会更容易:这就是调试构建的目的。
因此,也许我们应该学会使用这种语言,而不是专注于UB:
突然间一切都好起来了:)
发布于 2010-05-05 09:19:45
我对未定义行为的看法是:
该标准定义了如何使用该语言,以及当以正确的方式使用时,实现应该如何作出反应。然而,要涵盖每个功能的每一种可能的使用都需要做大量的工作,因此标准只留下了它。
但是,在编译器实现中,不能仅仅“保留它”,代码必须转换为机器指令,而且不能只留下空白处。在许多情况下,编译器可能会抛出错误,但这并不总是可行的:在某些情况下,需要额外的工作来检查程序员是否做错了事情(例如:两次调用析构函数--为了检测这一点,编译器必须计算某些函数被调用了多少次,或者添加额外的状态或其他什么)。因此,如果标准没有定义它,而编译器只允许它发生,那么如果你运气不好的话,机智的事情有时会发生。
发布于 2010-05-05 09:18:04
这些问题不是由未定义的行为引起的,而是由编写导致问题的代码引起的。答案很简单--不要写那种代码--不这样做并不完全是一门科学。
至于:
一个未定义行为的示例,在运行时或编译时无法在没有相当开销的情况下检测到这些行为。
一个现实世界的问题:
int * p = new int;
// call loads of stuff which may create an alias to p called q
delete p;
// call more stuff, somewhere in which you do:
delete q;在编译时检测到这一点是不可能的。在运行时,这仅仅是极其困难的,并且需要内存分配系统做更多的记账工作(即要慢一些,占用更多的内存),如果我们简单地说第二次删除没有定义的话。如果您不喜欢这样,那么C++可能不是您的语言--为什么不切换到java呢?
https://stackoverflow.com/questions/2771825
复制相似问题