什么是合同(针对 C++17 提出的建议)? [英] What are contracts (as proposed for C++17)?

查看:49
本文介绍了什么是合同(针对 C++17 提出的建议)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 关于合同的思考B. Stroustrup 编写的 C++17 并协助进行了一次关于它们的小型演示,但我不确定我是否真的理解它们.

I read about contracts in Thoughts about C++17 by B. Stroustrup and assisted a small presentation talking about them but I am not sure I have understood them really.

所以我有一些疑问,如果可以用一些例子来说明它们:

So I have some interrogations and if it is possible to illustrate them with some examples :

  • 契约是否只是经典 assert() 的更好替代品,它们是否应该一起使用?对于软件开发人员来说,哪些合同真的很简单?

  • Are contracts just a better replacement of the classic assert(), and should they be used together? What contracts really are put in simple terms for a software dev?

合同会影响我们处理异常的方式吗?如果是,我们应该如何使用例外和合同?

Would contracts have an impact on how we handle exceptions? If yes, how should we use exceptions and contracts?

使用合约是否意味着执行时的开销?我们会被允许在发布代码上停用它们吗?

Would using contracts imply an overhead at execution time? Will we be allowed to deactivate them on release code?

来自 提案 N4415:

Vector 类的索引操作符的前置条件契约可以写成:
<代码>T&运算符[](size_t i) [[期望:i <size()]];

A pre-condition contract of the indexing operator of a Vector class could be written:
T& operator[](size_t i) [[expects: i < size()]];

类似地,ArrayView 类的构造函数上的后置条件契约可以表示为:ArrayView(const vector& v) [[确保:data() == v.data()]];

Similarly, a post-condition contract on a constructor of an ArrayView class could be expressed as: ArrayView(const vector<T>& v) [[ensures: data() == v.data()]];

感谢@Keith Thompson 评论:

Thanks to @Keith Thompson comment:

契约没有进入 C++20.一个新的研究小组,SG21,已创建.

推荐答案

据我阅读本文档:http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4415.pdf

合约做assert多年来一直试图以原始方式做的事情.它们既是文档,也是关于调用者应该如何调用函数以及在函数返回后调用者期望代码处于什么状态的运行时断言.这些通常称为前置条件和后置条件,或不变量.

Contracts do what assert has been trying to do in a primitive way for years. They're both documentation and a run-time assert of how the caller should be expected to call the function and in what state can the caller expect the code to be after the function has returned. Those are usually known as pre-conditions and post-conditions, or invariants.

这有助于清理实现方面的代码,因为通过契约,我们可以假设一旦执行进入您的函数,您的参数处于有效状态(您期望它们是什么).

This helps clean up code on the implementation side, because with contracts we can assume that once the execution has gone inside your function, your arguments are in valid state (what you expect them to be).

后置条件部分可能会改变您处理异常的方式,因为对于合同,您必须确保抛出异常不会破坏您的后置条件.这通常意味着您的代码必须是异常安全的,尽管这意味着强异常保证还是基本保证取决于您的条件.

The post-conditions part might change how you handle exceptions, because with contracts you will have to make sure that throwing an exception won't break your post-conditions. This usually means that your code has to be exception safe, though whether that means strong exception guarantee or basic guarantee depends on your conditions.

示例:

class Data;
class MyVector {
public:
    void MyVector::push_back(Elem e) [[ensures: data != nullptr]]
    {
        if(size >= capacity)
        {
            Data* p = data;
            data = nullptr; // Just for the sake of the example...
            data = new Data[capacity*2]; // Might throw an exception
            // Copy p into data and delete p
        }
        // Add the element to the end
    }
private:
     Data* data;
     // other data
};

在此示例中,如果 newData 的构造函数抛出异常,则违反了后置条件.这意味着您应该更改所有此类代码以确保您的合同不会被违反!

In this example here, if new or Data's constructor throws an exception, your post-condition is violated. This means that you should change all such code to make sure your Contract is never violated!

当然,就像 assert 一样,合约可能包含运行时开销.不同之处在于,由于合约可以作为函数声明的一部分,编译器可以进行更好的优化,例如在调用者站点评估条件,甚至在编译时评估它们.本文开头提到的文档的第 1.5 节讨论了根据您的构建配置关闭合约的可能性,就像普通的旧断言一样.

Of course, just like assert, contracts might include a run-time overhead. The difference though is that since contracts can be put as part of the function's declaration, the compiler can do better optimizations, such as evaluating the conditions at the caller's site or even evaluate them at compile time. Section 1.5 of the document mentioned at the beginning of this post talks about the possibilities of turning off contracts depending on your build configuration, just like plain old asserts.

这篇关于什么是合同(针对 C++17 提出的建议)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆