Reflection還沒通過,Contract就先進入下一版的C++標準當中了
如果要簡單講完Contract,大概就是C語言assert
的威力加強版吧
Before Contract
打開assert.h
你大概可以看到類似這樣的程式碼
1 |
|
甚至知名的Open Source Project,也會搞自己的一套assert機制
1 |
|
或是l
由於這個機制基於Macro,所以Macro Pollution是繞不開的問題
將Contract列如標準之後,有以下好處
- 避免Macro Pollution
- 更靈活的處理策略
- 由於是Language本身的一部分,之後有更好的工具可供分析使用
How to Use
最簡單的方法就是將assert
置換成`contract_assert
1 | auto w = getWidget(); |
基本行為就跟assert一致,不過可以透過Compiler控制Contract Semantics
Evaluation semantics
關於Contract,有四種不同的Evaluation方式
- Ignore
- Enforce
- Observe
- Quick-Enforce
這邊就不喜說了,需要的話參考Reference的連結
Pre and Post
這個也跟以前function用assert檢查Input跟Output Result差不多
1 | int f(const int x) { |
基本上沒什麼問題,只不過不能從FUnction signature中檢查,要深入Function body才知道問題出在哪
有了Contract之後,可以在函數宣告的地方加上pre
和post
表示前置和後置條件
1 | int f(const int x) |
就是把assert的使用情境細分
handle_contract_violation
有些時候,除了Compiler 內定的行為,我們需要自行對Contract做處理
這時候就是Global function handle_contract_violation
發揮的時刻
1 | // Try overriding the violation handler |
最後一行表示回到內建的處理方式了
Status
目前MSVC還未實作,省略不計
gcc和clang的用法略有不同
目前gcc的使用方式:
1 | -fcontracts -fcontracts-nonattr -fcontract-evaluation-semantic=enforce |
而clang則是:
1 | $ -fcontracts -fcontract-evaluation-semantic=enforce |
Reference
Contracts for C++ explained in 5 minutes
C++26启航:Safe C++的破晓时刻