/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */
#content_views .toc,
/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */
#content_views.markdown_views > p:empty:has(+ .toc),
#content_views.markdown_views > .toc + p:empty,
/* 富文本旧版目录标记 */
#content_views.htmledit_views #main-toc,
#content_views.htmledit_views #hr-toc,
#content_views.htmledit_views p[id*=\”-toc\”] {
display: none !important;
}
/* 目录去掉后,紧跟的首个标题不再多出一块上边距 */
#content_views.markdown_views > .toc + h1,
#content_views.markdown_views > .toc + h2,
#content_views.markdown_views > .toc + h3,
#content_views.markdown_views > .toc + h4,
#content_views.markdown_views > .toc + p:empty + h1,
#content_views.markdown_views > .toc + p:empty + h2,
#content_views.markdown_views > .toc + p:empty + h3,
#content_views.markdown_views > .toc + p:empty + h4 {
margin-top: 0 !important;
}
AI Coding Agent 已经可以根据静态分析告警修改代码、创建提交,甚至自动发起 Pull Request。真正棘手的问题却没有随之消失:PR 中的代码,是否就是被验证过的那一版代码?
在 C/C++ 项目中,一份“告警数已经下降”的报告并不足以回答这个问题。代码修改后,原报告中的行号可能偏移;宏定义、编译器模型或构建参数一旦变化,静态分析实际覆盖的条件编译分支也可能不同。更危险的是,AI 可能消除了规则违规,却同时改变了函数行为。
因此,AI 修复不能停在“生成补丁”。一条可用于工程实践的链路,至少应包含四步:
C/C++test 发现违规
↓
AI Agent 按规则修改代码
↓
C/C++test 在相同构建上下文中重新分析
↓
工程师结合代码差异、测试结果和最终报告决定是否合并
下面结合 Parasoft 官方 AI Agent Demo,拆解这条链路中的关键实现。
1. 为什么不能拿旧报告验证新代码
静态分析结果并不是脱离工程环境存在的一组行号。对于包含大量宏、条件编译和平台差异的 C/C++ 项目,分析结果至少与以下信息有关:
- 被分析的提交版本;
- 实际参与构建的源文件;
- 编译器及其语言扩展;
- 宏定义、头文件搜索路径和编译选项;
- 启用的规则集、抑制配置和分析范围。
如果 AI 修改的是提交 B,审查者拿到的却是提交 A 的报告,那么“告警已消失”就没有可追溯的依据。即使两次报告采用相同的规则配置,只要构建上下文不同,结果也不能直接比较。
这也是 Parasoft C/C++test 在流程中的第一个作用:它不仅输出告警,还可以基于真实构建信息建立可重复的分析入口。
2. 先捕获真实构建,再运行静态分析
Parasoft 官方 Demo 使用 cpptesttrace 跟踪项目的实际构建,生成 cpptestscan.bdf。BDF(Build Data File)记录源文件及其编译参数,随后交给 C/C++test 执行分析。
官方 GitHub Actions 工作流中的核心配置可简化为:
– name: Build and capture build data
run: cpptesttrace make clean all
– name: Run C/C++test
uses: parasoft/run–cpptest–action@2
with:
input: cpptestscan.bdf
testConfig: "builtin://Recommended Rules"
compilerConfig: gcc_13–64
additionalParams: –fail
这里有三个不能随意省略的参数:
additionalParams: -fail 可以让分析结果影响流水线状态,但它只是质量门禁的一部分。对于 AI 自动修复场景,还需要把分析再次放回修改循环。
3. 把复扫做成 AI 修复循环的一部分
官方 Demo 在项目根目录提供了 cpptest-analyze.sh,作为 Agent 重新分析代码的统一入口:
#!/bin/bash
set -euo pipefail
cpptesttrace make clean all
cpptestcli -quiet -compiler gcc_13-64 \\
-config "builtin://Recommended Rules" \\
-module . \\
-input cpptestscan.bdf
这段脚本的重点并不是命令本身,而是把“重新构建、重新捕获 BDF、按照固定配置分析”绑定在一起。Agent 每完成一轮修改,都通过同一个入口得到新的 reports/report.xml,避免修改代码后继续读取旧结果。
C/C++test 的 MCP Server 则负责把分析结果和规则知识交给 AI Agent。与这一流程直接相关的工具包括:
- get_violations_from_report_file:从 XML 报告提取违规,可按规则 ID、严重级别和源文件过滤;
- count_violations_in_report_file:统计指定条件下的违规数量;
- get_rule_documentation:获取规则说明、违规原因及修复参考。
官方 cpptest-fix-all-violations Skill 采用“按规则处理”的策略:先选择严重级别最高的规则,再处理该规则的全部违规,每轮修改后重新运行分析。其控制逻辑可以用下面的伪代码表示。
以下代码用于说明流程,不是 Parasoft 官方脚本原文。
rules_processed = 0
while rules_processed < rules_limit:
run("./cpptest-analyze.sh")
violations = mcp.get_violations("reports/report.xml")
if not violations:
break
rule_id = select_highest_severity_rule(violations)
rule_doc = mcp.get_rule_documentation(rule_id)
for attempt in range(iteration_limit):
apply_minimal_fix(rule_id, rule_doc)
run("./cpptest-analyze.sh")
remaining = mcp.get_violations(
"reports/report.xml",
rule_id=rule_id
)
if not remaining:
commit_fix_for(rule_id)
break
rules_processed += 1
这种做法解决了两个常见问题:
- 不会因为修掉一个位置,就误判整条规则已经处理完成;
- 达到尝试上限后可以停止并保留问题,而不是让 Agent 无限修改代码。
官方 Skill 默认将单条规则的尝试次数限制为 3,将单次任务处理的规则数限制为 20;如果启用自动提交,则在一条规则通过复查后单独提交。这些限制不是为了降低自动化程度,而是为了控制一次 Agent 任务的修改范围,让回滚和人工审查更容易。
4. 过程复扫不等于最终 PR 已被验证
这里还有一个容易被忽略的工程细节:修复过程中运行过 C/C++test,不代表 CI 中归档的报告就一定对应最终 PR。
在 Parasoft 官方 GitHub Actions Demo 中,首次报告归档发生在 AI Autofix 之前。Agent 后续虽然会多次调用分析脚本,但这些中间报告不会自动成为最终待审提交的 CI 附件。
如果报告要作为合并门禁或审计证据,建议在 AI 推送修复提交后,对最终 HEAD 再执行一次独立分析,并同时记录提交 SHA。下面是一种流水线写法:
– name: Record analyzed commit
shell: bash
run: echo "ANALYZED_SHA=$(git rev–parse HEAD)" >> "$GITHUB_ENV"
– name: Final C/C++test verification
run: ./cpptest–analyze.sh
– name: Archive final report
uses: actions/upload–artifact@v4
with:
name: cpptest–report–${{ env.ANALYZED_SHA }}
path: reports/
这段配置是面向实际项目的补充示例,并非官方 Demo 原样代码。落地时还应在报告元数据或流水线产物中保留以下信息:
commit SHA + test configuration + compiler configuration + analysis scope
审查者还需要确认目标规则确实处于启用状态、相关文件被纳入分析,并排除“通过新增抑制让告警消失”的情况。只有这样,报告、提交和代码差异才能相互对应。
5. 规则通过,为什么仍然不能直接合并
静态分析复扫能够验证目标规则是否仍被触发,但它不能替代对业务行为的判断。Parasoft 官方示例项目 Bank.cxx 中,getAccount() 的核心代码如下:
Account* Bank::getAccount(int num, string password)
{
Account* userAccount = NULL;
if (myAccounts.size() > num)
{
userAccount = (Account*)myAccounts[num];
}
if ((userAccount != NULL) &&
(password.compare(userAccount->getPassword()) != 0))
{
userAccount = NULL;
}
return NULL;
}
对于要求在 C++11 及以上代码中优先使用 nullptr 的规则 CODSTA-MCPP-04,下面的修改消除了规则违规,同时保持了原有返回行为:
– return NULL;
+ return nullptr;
但如果 AI 根据上下文“顺手修正”成:
– return NULL;
+ return userAccount;
对应行同样不再触发 NULL 相关规则,函数语义却发生了变化:索引有效且密码正确时,调用方可能从始终得到空指针,变为获得账户指针。
这个例子说明了三类验证职责的边界:
| 规则状态 | C/C++test | 目标违规是否消失,是否引入新的静态分析问题 |
| 修改意图 | AI Agent + 代码审查者 | 补丁是否只做了必要修改,是否符合接口约定 |
| 运行行为 | 单元测试/集成测试 + 工程师 | 修改是否改变正常路径、异常路径和边界条件 |
因此,“C/C++test 复扫通过”应被视为合并依据之一,而不是合并结论本身。对于可能改变控制流、返回值、资源生命周期或并发行为的补丁,还应补充相应的单元测试和回归测试。
6. 在项目中落地时,至少设置这四道检查
如果准备把 AI 修复接入现有 C/C++ CI/CD,可以先从以下四项开始:
对于安全关键或强合规项目,还需要根据组织流程增加人工批准、变更追踪、基线管理和测试证据。AI Agent 可以减少重复定位、逐条查阅规则和反复运行分析的操作,但不应绕过既有的软件安全与质量流程。
结语
AI 对 C/C++ 静态分析告警的价值,不只是把代码“改得更快”。更重要的是,让每次修改都能重新进入同一套分析机制,并把可核对的结果交给审查者。
在这条链路中,Parasoft C/C++test 提供真实构建上下文、规则化分析、结构化报告和 MCP 工具;AI Agent 根据规则信息生成并迭代修改;工程师则结合最终报告、代码差异和测试结果决定是否合并。三者各自承担明确职责,自动修复才不会从“提效工具”变成新的质量盲区。
网硕互联帮助中心


评论前必须登录!
注册