Herb发布了一个关于未来在ACUU会议上的讲话的C++异常和即将签订的合同,以取代或增强现有的断言。
他假定有以下规则来处理错误处理:
虽然我同意,但我并没有使用这种方法,而是将2和3本质上结合在一起。我这么做是因为我不知道如何测试断言或即将签订的合同。两者都使用类似的机制,它们的违规导致程序终止,并在此之前调用可选处理程序。
来自文档 (重点是我的):
程序可以使用以下两种违反延续模式之一进行翻译:
鼓励实现不提供任何编程方法来查询、设置或修改构建级别,或者设置或修改冲突处理程序.。
这意味着,将根据合同进行测试的测试程序需要额外的编译开关。虽然我不喜欢这样做,但我理解为什么会这样做。更令人担忧的是最后一部分,以及关于它的问题,已被提出。如果设置我们自己的合同违约处理程序的能力是实现定义的,那么它将在各个工具链之间不一致。因此,如果可能的话,对合同的任何测试都是不可携带的。将其设置为链接器的另一个参数也会非常尴尬(而且肯定不是可移植的)。
目前,对assert进行测试是不可能的,因为它只是中止程序,而且据我所知,自定义处理程序无法阻止这一点。对于契约,这应该可以使用自定义处理程序和构建开关,但事实证明,它可能也不可能(或者是实现定义的)。
或者,是否有其他方法来测试断言和合同是否有可能使我失踪?
发布于 2019-05-03 14:46:19
在违反合同方面没有太多的执行差异。"构建水平“决定合同检查是否发生。对于任何已检查的失败的合同,都将调用违规处理程序。
规范定义了处理程序的原型。与冲突处理程序有关的唯一实现差异是如何设置它。请注意,“实现定义”并不意味着“不允许这种情况发生”。也就是说,是建立处理程序的机制。,这个机制将与实现一起记录下来(这就是“实现定义”的意思,而不仅仅是“未指定的”)。确切地说,这一机制将取决于实现,但不提供这种机制并不是一种选择。
唯一可能出现的真正问题是,如果多个实现决定允许用户通过祝福特定的全局名称来指定处理程序,以及这些实现是否使用不同的全局名称。但是,由于许多原因(与现有代码、宏等冲突),选择一个全局名称是个坏主意,这在现实中不太可能是个问题。因此,更有可能的是,他们会选择明显的机制:一个编译器开关,它指定要用作处理程序的函数的名称。
注意,使处理程序的定义是静态的而不是运行时定义的原因之一是确保开关是编译器开关而不是链接器开关。毕竟,编译器是一个会发出任何概念检查代码的编译器。因此编译器只需在所述检查代码中使用所述函数的名称即可。
当然,不同的编译器可能/将有不同的编译器开关来建立调用哪个函数。但是他们已经有了不同的开关来生成调试信息,优化级别,以及基本上所有其他的东西。因此,无论您使用的是什么跨平台测试系统,都需要能够处理这些差异。违规处理程序只是另外一个。
https://stackoverflow.com/questions/55964700
复制相似问题