我目前正在阅读有关设计合同/代码合同的更多信息。据我所知,它是编写合同(不变量、前置条件和后置条件),以确保代码可以有序维护。它还通过基于检查和平衡的良好定义机制来保证预防错误。
但是,这难道不会影响软件性能吗?因为每个方法调用之间都会有额外的检查。
我非常感谢人们与我分享有关设计合同的观点和经验。缺点或优点都受欢迎。
但是,这难道不会影响软件性能吗?因为每个方法调用之间都会有额外的检查。
我非常感谢人们与我分享有关设计合同的观点和经验。缺点或优点都受欢迎。
应用设计契约哲学的一种方法是完全静态的。考虑一个函数max_element()
的契约:
/*@
requires IsValidRange(a, n);
assigns \nothing;
behavior empty:
assumes n == 0; ensures \result == 0;
behavior not_empty:
assumes 0 < n;
ensures 0 <= \result < n;
ensures \forall integer i; 0 <= i < n ==> a[i] <= a[\result]; ensures \forall integer i; 0 <= i < \result ==> a[i] < a[\result];
complete behaviors;
disjoint behaviors;
*/
size_type max_element(const value_type* a, size_type n);
requires
条款的参数调用函数时,ensures
子句中的后置条件得到满足,则无需为后置条件生成检查。同样地,如果你验证所有调用方在满足自己的前置条件时仅使用满足其前置条件的参数调用max_element()
,则不需要在函数入口处进行检查。以上示例来自ACSL by Example。该库提供了ACSL中的许多函数契约。这些合同的C实现已经被静态正式验证,以确保对于满足前置条件的所有调用,后置条件都成立。因此,后置条件不需要运行时检查。编译器可以将注释视为注释(它们使用/*@ ... */
语法)。设计契约旨在确保正确的实现 - 代码在调用方和被调用方之间的预期API方面是正确编写的。理想情况下,您可以使用静态分析工具和开发和alpha测试环境中的运行时检查来验证是否遵守了合同。希望到那时,您已经捕获了与API错误相关的任何实现错误。除非您试图跟踪错误,否则在beta和生产中可能不会使用运行时检查。