如何解释未知行为以了解所有新手?

sha*_*oth 35 c++ undefined-behavior

有一些情况,C++标准将其定义为未定义的行为.例如,如果我分配new[],然后尝试释放delete(不delete[])那是未定义的行为 - 任何事情都可能发生 - 它可能会起作用,它可能会崩溃,它可能会默默地破坏某些东西并设置一个定时问题.

解释这一点很有问题,新手可能会发生任何事情.他们开始"证明""这是有效的"(因为它确实适用于他们使用的C++实现),并询问"这可能是什么问题"?我能给出什么简洁的解释会激励他们不写这样的代码?

Ale*_*eth 48

未定义意味着明确不可靠.软件应该可靠.你不应该说太多其他的话.

冰冻的池塘是未定义的行走表面的一个很好的例子.仅仅因为你跨过一次并不意味着你应该在你的纸张路线上添加快捷方式,特别是如果你计划四季.

  • 想象力+1,有时一张图片胜过千言万语. (7认同)

Pét*_*rök 32

我想到了两种可能性:

  1. 你可以问他们"只是因为你可以在午夜时分在高速公路上朝相反的方向行驶并继续生存,你会经常这样做吗?"

  2. 更复杂的解决方案可能是设置不同的编译器/运行环境,以向他们展示在不同情况下它是如何失败的.

  • 解决方案2的难点在于您可能会发现没有一个可用的编译器实际上失败了,但行为仍未定义,因此无法依赖.太多的代码用"我找不到它破坏的地方"编写,虽然目前可能是这种情况,但是某些东西可能会改变(平台,编译器......),这将使它在未来中断 - 并且没有系统中的错误,因为行为未定义(所以任何事情都是正确的).还要在comp.std.c新闻组中搜索"nasal demons". (4认同)

Ign*_*ams 21

"恭喜,你已经定义了编译器对该操作的行为.我希望明天上午10点之前关于世界上存在的其他200个编译器的行为的报告出现在我的桌面上.不要让人失望我现在,你的未来看起来很有希望!"

  • 更大的问题是,当使用稍微不同的源或选项(甚至在一天中的不同时间或在不同的机器上)编译时,相同的编译器可能表现出不同的行为.因此,对于未定义的行为,您甚至不能真正说'那是特定编译器的作用' - 这就是'实现指定'行为的用途. (19认同)

fre*_*low 14

只需引用标准.如果他们不能接受,那么他们就不是C++程序员.基督徒会否认圣经吗?;-)

1.9程序执行

  1. 本国际标准中的语义描述定义了参数化的非确定性抽象机器.[...]

  2. 抽象机的某些方面和操作在本国际标准中描述为实现定义的(例如sizeof(int)).这些构成了抽象机器的参数.每个实施应包括描述其在这些方面的特征和行为的文件.[...]

  3. 抽象机器的某些其他方面和操作在本国际标准中被描述为未指定的(例如,对函数的参数的评估顺序).在可能的情况下,本国际标准定义了一组允许的行为.这些定义了抽象机器的非确定性方面.[...]

  4. 本国际标准中将某些其他操作描述为未定义(例如,取消引用空指针的效果).[注意:本国际标准对包含未定义行为的程序的行为没有要求. - 尾注]

你不能比这更清楚.

  • *"基督徒会否认圣经吗?"* - 嘿,你可能会感到惊讶...... (11认同)

小智 12

我要解释一下,如果他们没有正确编写代码,他们的下一次性能评估就不会很开心.对大多数人来说,这是充足的"动力".