You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何g++/clang++报"does not give a valid preprocessing token"编译错误

结论

GCC和Clang的编译报错是符合C++标准的正确行为,MSVC(cl.exe)默认允许代码通过属于非标准扩展,并非GCC/Clang的问题。

原因解释

C/C++预处理器的##运算符作用是将前后两个预处理Token拼接为一个新的合法预处理Token,标准明确要求拼接后的结果必须是有效的预处理Token,否则行为未定义。
你代码中&Test::##testName的写法,是尝试把::标点Token和testName对应的标识符Token(比如展开后的test1、test2)拼接为一个Token,但::test1本身不属于任何一类合法的预处理Token(合法预处理Token包括关键字、标识符、字面量、独立运算符/标点等),所以属于非法用法。

MSVC默认没有开启标准兼容的预处理器,对##的校验逻辑宽松,会直接将两个Token的字面文本拼接后输出,所以没有报错。如果给MSVC加上/Zc:preprocessor编译选项开启标准兼容预处理器,也会抛出和GCC/Clang一致的错误。

正确写法

你已经用到的修改方案就是标准写法:直接去掉##,写为&Test::testName即可。::和后面的方法名本身就是两个独立的合法预处理Token,预处理器展开后会被C++语法解析器正确识别为类成员指针,完全不需要额外拼接。


内容的提问来源于stack exchange,提问作者Manthan Tilva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 14:09:03