1.现象
目前我在工程中试图使用QHttpServer时,一编译,就报了一堆奇奇怪怪的错误:
D:\Qt\httpServer\Qt5.15.2\include\QtHttpServer\qhttpserverrequest.h:75: error: C2143: 语法错误: 缺少“}”(在“(”的前面)
D:\Qt\httpServer\Qt5.15.2\include\QtHttpServer\qhttpserverrequest.h:75: error: C2059: 语法错误:“常数”
D:\Qt\httpServer\Qt5.15.2\include\QtHttpServer\qhttpserverrequest.h:81: error: C2143: 语法错误: 缺少“;”(在“}”的前面)
D:\Qt\httpServer\Qt5.15.2\include\QtHttpServer\qhttpserverrequest.h:81: error: C2238: 意外的标记位于“;”之前
D:\Qt\httpServer\Qt5.15.2\include\QtHttpServer\qhttpserverrequest.h:82: error: C2255: “friend”: 不允许位于类定义之外
D:\Qt\httpServer\Qt5.15.2\include\QtHttpServer\qhttpserverrequest.h:82: error: C2065: “Method”: 未声明的标识符
D:\Qt\httpServer\Qt5.15.2\include\QtHttpServer\qhttpserverrequest.h:82: error: C2365: “qt_getEnumMetaObject”: 重定义;以前的定义是“函数”
......
怎么会这样?我记得之前我用得好好的啊。
经过一番排查,发现了问题。是open62541.h的问题。
只要把这个头文件放在QtHttpServer的后面就可以了。
2.具体原因分析
2.1.解决办法
原因是DELETE这个名称被宏定义了,然后QHttpServerRequest中又使用到它,然后在展开宏预处理时就被替换了(详情请看2.2)。
解决办法:
#include "open62541.h"
#undef DELETE // 加这个就行
#include "QtHttpServer/qhttpserverrequest.h"
#include "QtHttpServer/qhttpserver.h"
2.2.分析,debug的过程
首先,我们先按照会触发编译错误的方式写:
然后双击下面的第一条报错,跳到出错的位置
在这里直接看,其实看不出哪里错误的。但是,在出错的这一行,按着ctrl键,然后用鼠标点击那个DELETE。
立马跳转到winnt.h这里了:
一看,好家伙,原来这个DELETE是在这里被宏定义了。不难猜到,这个winnt.h肯定是open62541.h带进来的。
那就好办了。
在include头文件时,先#include “open62541.h”,然后再将这个DELETE取消宏定义。也就是前面说的
#include "open62541.h"
#undef DELETE // 加这个就行
#include "QtHttpServer/qhttpserverrequest.h"
#include "QtHttpServer/qhttpserver.h"
看到这个导致错误的原因,不禁让人想起那个经典笑话:
#define true false
#define false true
3.总结
啊,真是一场酣畅淋漓的debug。
总之见到这种明显不是语法错误,但是在编译时报语法错误的问题,都可以考虑是不是宏定义的问题(也有可能是中文+编码的问题)。