C++中[[expects]]属性无法工作 编译报expected ']' before ':'错误
问题根本原因
[[expects: ...]]不是任何正式发布的C标准支持的语法。它是C20制定阶段被临时否决的「契约特性」提案里的草稿设计,最终没有进入C20正式标准,后续C23也未纳入该特性,目前GCC、Clang、MSVC所有稳定版编译器的默认编译模式都无法识别这个写法,解析到属性内的冒号时就会抛出error: expected ']' before ':' token语法错误。- 你查到的相关资料大多基于当年的提案草稿撰写,描述的是从未正式落地的实验性设计,不能直接作为正式语法使用。
- 即便部分编译器提供了契约特性的实验分支实现,语法也已经和早年草稿的
[[expects:]]有较大差异,且默认是关闭状态,直接编写必然编译失败。
可行修复方案
方案1:使用标准语法实现前置条件校验(通用无兼容问题,推荐)
不需要依赖未落地的实验特性,直接在函数入口做校验即可,所有C++版本均可正常编译运行:
如果需要调试阶段触发终止报错,用标准库断言:
#include <iostream> #include <cassert> void something(int i) { assert(i != 1); // 前置条件校验,Debug模式下传1会触发断言终止 std::cout << i << "\n"; } int main() { something(3); something(2); something(1); return 0; }
如果需要抛出可捕获的异常,替换为判断+抛出逻辑即可:
#include <iostream> #include <stdexcept> void something(int i) { if (i == 1) { throw std::invalid_argument("Precondition failed: i cannot be 1"); } std::cout << i << "\n"; } int main() { something(3); something(2); something(1); // 这里会抛出异常 return 0; }
方案2:使用编译器实验性契约实现(仅适合测试,不推荐生产环境使用)
如果一定要使用属性风格的前置条件写法,需要使用支持契约实验特性的编译器构建版本,开启对应编译开关。注意目前实验实现的语法已经改为[[pre: 表达式]],而非早年草稿的[[expects:]],例如支持契约的GCC分支需要添加-fcontracts编译参数才能开启相关功能。实验特性的语法和行为随时可能调整,不建议在正式项目中使用。
内容的提问来源于stack exchange,提问作者BadUsernameIdea
相关产品推荐
相关产品推荐

