ATL/WTL生成的_Module等标识符是否违反C++命名规则?
关于ATL/WTL生成的下划线开头标识符的合规性问题
首先直接给结论:这些标识符严格来说属于C++标准中规定的保留标识符,用户编写的代码(包括项目中自定义的部分)不应该使用这类命名,但框架自动生成的代码在特定环境下可以继续使用,是否重命名取决于你的需求。
先理清C++标准里的保留标识符规则
C++标准对标识符的使用有明确限制,核心两条和这些符号相关:
- 任何以下划线开头,且紧跟大写字母的标识符(比如
_Module、_Handler),无论处于哪个命名空间,都是保留给编译器和标准库实现使用的——用户代码绝对不能定义或使用这类标识符。 - 全局命名空间中,任何以下划线开头的标识符(哪怕后面是小写字母或数字),同样是保留的,用户不能在全局空间声明这类符号。
为什么ATL/WTL会用这些命名?
这属于历史遗留问题:ATL/WTL诞生较早,当时C++标准的规则执行没那么严格,微软作为框架开发者,为了内部标识的区分,采用了这类命名。而MSVC编译器对自家框架的写法做了兼容,所以在Windows+MSVC的环境下,直接使用这些自动生成的代码通常不会有编译或运行问题。
要不要重命名?
分两种情况来看:
- 如果是框架向导自动生成的代码:比如全局的
_Module变量,如果你只在MSVC环境下开发,且项目完全依赖ATL/WTL,继续使用也没问题——微软的生态会兼容这种写法。但如果你的代码需要考虑跨编译器移植,或者追求严格的标准合规性,那建议重命名(比如改成g_Module、GlobalModule这类符合标准的命名),不过要注意修改所有引用该变量的地方,避免编译错误。 - 如果是你自己编写的代码:绝对不要用
_Module、_Handler这类命名,换成常规的命名方式(比如前缀g_表示全局变量,或者用更具语义的名称,比如AppServiceMain),避免触发标准的保留标识符限制,也让代码更易读。
补充:关于用户命名空间中的_Handler、_ServiceMain
即使这些符号在你自己的命名空间里,_Handler(H大写)依然属于标准保留的标识符范畴,严格来说是不允许的。如果是下划线后面跟小写字母(比如_handler),在用户命名空间里是合规的,但为了代码风格统一和可读性,还是建议避免用下划线开头的命名。
内容的提问来源于stack exchange,提问作者vbstb
相关产品推荐
相关产品推荐

