Skip to content

模块扫描器不剥块注释:/* */ 里的 import 被当成真的模块导入 #373

Description

@speak-agent

症状

任何在 /* ... */ 块注释里出现 import <name>; 的源文件,都会被扫描器当成真的模块导入,于是每次构建刷一条:

warning: .../compat-x-abseil/20250512.1/abseil-cpp-20250512.1/absl/random/internal/randen_round_keys.cc:
         module 'binascii' imported but not provided in this build

abseil 把生成该数组的 Python 脚本原样嵌在文件头部:

// "Nothing up my sleeve" numbers from the first hex digits of Pi ...
// Python script:

/*
python >tmp.cc << EOF
"""Generates Randen round keys array from pi-hex.62500.txt file."""
import binascii            ← 这一行

KEYS = 17 * 8

binascii 是 Python 标准库,不是 C++ 模块。任何 grpc/abseil 消费者每次构建都会看到这条,本次 mcpp-index CI 的 linux 与 macOS 日志里都有。

根因

src/modgraph/scanner.cppm 已经处理了同一类假阳性的两种来源,唯独漏了块注释:

  • strip_line_comment()(:137)—— // 行注释

  • strip_raw_strings()(:155)—— raw-string 体,注释里写明了动机:

    Without this, a template that embeds source text — e.g. the mcpp new --template gui skeleton stored as R"GUI( ... import imgui.core; ... )GUI" … has its inner import lines misdetected as real module imports, producing spurious "imported but not provided" warnings.

这是同一模式的第三次:凡是「源文件里嵌着看起来像代码的文本」,匹配器就会中招。/* */ 是最后一种常见形态,而且它比前两种更容易撞上——嵌脚本、贴示例、注释掉一段旧代码,都会产生它。

匹配器只在「trim 后以关键字开头」的行上触发,所以普通 "..." 字符串不受影响;块注释里的行恰恰满足这个条件。

建议

strip_raw_strings 同一层加块注释剥离,跨行状态与它一样用 bool& in_block 传递(/**/ 可以同行、可以嵌在 raw string 里,顺序上应当先 raw-string 后块注释,或一次扫描同时处理两种状态)。

影响面

仅告警,不影响构建正确性——但它出现在每个 grpc / abseil 消费者的每次构建里,而「imported but not provided」在其它场合是真问题的信号,长期刷屏会把这条诊断训练成噪声。

复现

任意工程加一个 .cc:

/*
import binascii
*/
int main() { return 0; }

mcpp build 即出现该 warning。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions