# 低版本Qt moc在namespace处报错的问题分析与解决 由于不可描述的原因,需要在XP下强行编译一个标注了兼容性`C++17 & Qt 5.9`的程序。XP的平台限制很大,目前来看,最靠谱的技术路线是修改项目源码使其兼容`Qt 5.5`。 [[:Coding:Cpp:How_to_compile_cpp14_under_windows_XP|其他折腾点的背景信息在此:Windows XP下编译C++14/17程序手记]],本文不再详述。编译`Qt 5.5`时,由一个选项当时就引起了我的注意,叫是否启用`C++11`。按我的想法,`C++11`是否启用难道不是我的编译环境决定的吗?不过没有深究,开启了事。 然后按部就班`CMake`,`make`,不带GUI的部分顺利通过编译,然后GUI部分在`moc`阶段出事了。 [qt中moc的作用](https://blog.csdn.net/lcjwxd/article/details/20706673) 可恨的是`moc.exe`只报错误,不解释错误原因,连个错误类型提示都没有,只有行号和关键词。为了寻找问题共性,我仿照出错的命令手写了其他几条命令分别处理不同的文件,最后发现出错点总是在某个文件的`namespace xx::oo{`处报`xx`错误。按照这个思路搜索,发现了一条有意思的信息: > [Qt MOC error for namespace like FOO::BAR](https://stackoverflow.com/questions/22305609/qt-moc-error-for-namespace-like-foobar) 一个人说他把`namespace xx::oo{`改成`namespace xx{ namespace oo{`就可以避免问题,这`moc`是出啥毛病了?另一人说你才出毛病了,`namespace`本来就不能那么写。听起来像是一个不标准扩展问题,类似以前的`#program once`这种。针对这个继续搜索,发现了[CppReference/namespace](http://en.cppreference.com/w/cpp/language/namespace)的一条信息,人家明确指出: {{:coding:cpp:namespace_cpp17.png?direct|CppReference}} 显然,这是一个`C++17`引入的新的写法。我可以用`gcc 7.2`去编译`Qt 5.5`的库文件和整个工程,前半部分都没错。但`Qt 5.5`中附带的`moc.exe`毕竟是来自于`C++17`发布以前的代码,不会因为它是被`gcc 7.2`编译出来的就神奇地认识`C++17`的写法了。 这就比较麻烦了,我要编译的整个工程几乎每个文件都有`namespace xx::oo{`这种写法,改下去岂不是累死人。多亏图灵保佑,我搜索时还恰好看到了这个帖子: [QMake moc files confused by namespaces](https://stackoverflow.com/questions/18626146/qmake-moc-files-confused-by-namespaces) 此贴跟我的问题实质上毫无关系,只是恰好具有一样的关键词。文中提到,使用以下宏包装语句,可以使得这部分语句对于`moc`隐身: ``` #ifndef Q_MOC_RUN ... #endif ``` 更加幸运的是,我要编译的这个工程虽然挺大,但GUI部分与计算部分做了严格区分。计算部分没有任何一处包括`moc`所关注的`Q_OBJECT`。因此,我可以把所有`#include`了计算代码的段落用上面的宏包起来,不要让`moc`顺着`#include`进去瞎逛。至于GUI部分的`namespace xx::oo{`什么的,总共只有十来个文件,手动改一改还可以接受。改完编译,`moc`,`uic`再到`rcc`都顺利进行,问题解决!