CLARC: C/C++ Benchmark for Robust Code Search¶
会议: ICLR 2026
arXiv: 2603.04484
代码: GitHub / HuggingFace
领域: 代码检索 / 软件工程 / 代码理解
关键词: 代码检索, C/C++ 基准, 编译验证, 代码嵌入, 汇编语言, 鲁棒性
一句话总结¶
构建首个可编译的 C/C++ 代码检索基准 CLARC(6717 查询-代码对),自动化 pipeline 从 GitHub 提取代码并用 LLM+假设检验生成/验证查询;覆盖标准/匿名化/汇编/WebAssembly 四种检索场景,揭示现有代码嵌入模型过度依赖词汇特征(匿名化后 NDCG@10 从 0.89 降至 0.67)且在二进制级别检索上严重不足。
研究背景与动机¶
- 领域现状:代码检索基准主要针对 Python/Java(如 CodeSearchNet、CoSQA、COIR),基于嵌入的检索模型(Voyage-code-3、OpenAI embedding 等)是大规模检索的标准。
- 现有痛点:
- 语言覆盖偏颇:C/C++ 是系统编程核心语言,但主流基准忽略/不重视 C/C++ 的 text-to-code 检索
- 代码不可编译:现有基准中很多代码片段缺少 include/依赖,无法编译——与实际工程实践脱节
- 词汇依赖未被暴露:基准很少测试标识符重命名/匿名化下的鲁棒性——高分可能来自变量名匹配而非语义理解
- 二进制级别缺失:安全审计、逆向工程需要在汇编/二进制级别搜索代码,但没有基准评估这类能力
- 核心矛盾:代码检索模型声称理解"代码语义",但如果依赖的是变量名、函数名等词汇特征,那么在混淆代码/汇编代码上就会失灵
- 核心 idea:构建覆盖源码到二进制全栈的代码检索基准,用匿名化和编译到低级语言的方式系统性地测试语义理解 vs 词汇匹配
方法详解¶
数据集构建 Pipeline(四阶段)¶
- 数据收集
- 从 144 个 GitHub 热门 C/C++ 仓库挖掘函数(评估集 45 仓库 / 训练集 99 仓库)
- 建立编译环境白名单(标准库头文件)
- 提取每个函数及其完整依赖上下文(调用图 + 所需定义)
-
关键过滤:只保留能在准备环境中编译的函数——确保代码完整性
-
依赖复杂度分类
- Group 1(526 对):独立函数,无自定义类型/辅助函数依赖(平均 12.8 LOC)
- Group 2(469 对):依赖自定义类型但不依赖辅助函数(13.3 LOC)
- Group 3(250 对):依赖自定义类型和辅助函数(71.5 LOC,更长更复杂)
-
设计动机:不同依赖复杂度下的检索难度不同——需要理解上下文的代码更难检索
-
鲁棒性设置(四种场景)
- 标准源码:原始 C/C++ 代码
- 匿名化:所有变量名、函数名、类型名替换为无意义标识符(如
var_0、func_1)——剥离词汇线索,只留纯语义 - 汇编码:编译为 x86 汇编——模拟逆向工程场景
- WebAssembly:编译为 .wat 格式——模拟 Web 安全审计场景
-
设计动机:层层剥离高级特征,测试模型在不同抽象层上的真正理解能力
-
查询生成与验证
- LLM 生成自然语言查询(代码摘要任务)
- 假设检验验证:不只依赖 LLM 质量——用人类评分 + 统计假设检验确保查询质量。评估者打分后检验分数是否显著高于随机基线
- 设计动机:确保查询与代码的匹配不是 LLM 的幻觉
评估指标¶
- NDCG@10:排序质量
- Hole@10:top-10 中缺失的相关文档占比(越低越好)——衡量严重遗漏
实验关键数据¶
主实验(6 个模型 × 4 种场景)¶
| 模型 | 标准 NDCG@10 | 匿名化 NDCG@10 | 下降幅度 |
|---|---|---|---|
| Voyage-code-3 | 0.89 | 0.67 | -24.7% |
| OpenAI-embed-large | 0.85 | 0.60 | -29.4% |
| CodeT5+ | 0.72 | 0.55 | -23.6% |
| OASIS | 0.68 | 0.54 | -20.6% |
| Nomic-emb-code | 0.78 | 0.58 | -25.6% |
汇编/WebAssembly 检索¶
| 指标 | 平均表现 |
|---|---|
| 汇编 Hole@10(最佳模型) | ~17.1% |
| WebAssembly Hole@10 | 更高(性能更差) |
按依赖复杂度分析¶
| Group | 标准 NDCG@10 | 匿名化 NDCG@10 |
|---|---|---|
| Group 1(独立函数) | 最高 | 下降最多 |
| Group 3(复杂依赖) | 次之 | 下降较少 |
关键发现¶
- 匿名化后所有模型一致大幅下降(20-30%)——直接证明了模型依赖变量名/函数名等词汇特征而非真正理解代码语义
- 汇编级检索是重大挑战:最好的模型也有 17.1% 的相关文档遗漏——这意味着安全审计/逆向工程场景下代码检索基本不可用
- Group 1(独立函数)在匿名化后下降最大——可能因为独立函数更依赖描述性命名
- 商业模型(Voyage-code-3)在标准场景领先但匿名化后优势缩小——说明其"语义理解"部分来自更好的词汇匹配
- 专门优化鲁棒性的 OASIS 下降最小但绝对水平也不高
亮点与洞察¶
- "词汇依赖"的系统性证伪:通过匿名化这个干净的实验设计,直接量化了模型有多少性能来自词汇特征 vs 真正的语义理解。这对代码检索社区是重要的警示
- 全栈覆盖:从高级源码→匿名化→汇编→WebAssembly 的渐进式抽象剥离,是一个优雅的评估框架设计
- 可编译保证的价值:确保代码完整且有上下文——这使基准更接近实际工程场景,也让依赖复杂度分析成为可能
- 自动化 pipeline可复用——其他语言/项目可以用同样的流程构建类似基准
局限性 / 可改进方向¶
- 仅覆盖 C/C++,Python/Java/Rust 等语言的类似基准缺失
- 汇编级别仅测试了 x86 架构,ARM/RISC-V 等可能有不同特征
- 查询由 LLM 生成,可能与实际开发者搜索意图存在分布差异
- 评估集 1245 对的规模相对于 CodeSearchNet 等较小
- 未探索多阶段检索(先粗排再精排)或 RAG 场景
相关工作与启发¶
- vs CodeSearchNet:主要覆盖 Python/Go/Ruby 等,无 C/C++ text-to-code,不验证可编译性
- vs COIR:多任务代码检索基准但无匿名化/汇编级鲁棒性测试
- vs XCodeEval:有 C++ 但不来自真实项目
- 对代码嵌入模型的启示:当前模型在匿名化后大幅退化,说明需要更好的语义建模方法(如程序分析、控制流图、数据流分析)而非纯文本嵌入
评分¶
- 新颖性: ⭐⭐⭐⭐ 首个覆盖源码到二进制的可编译 C/C++ 代码检索基准,匿名化-编译的渐进式设计新颖
- 实验充分度: ⭐⭐⭐⭐ 6 个模型 × 4 种场景 × 3 种依赖复杂度 + 假设检验验证
- 写作质量: ⭐⭐⭐⭐ Pipeline 描述详细,统计验证严谨
- 价值: ⭐⭐⭐⭐⭐ 数据集贡献对代码检索和安全社区有持续价值,揭示了模型的关键弱点