来自 Qt 文件的编译时错误:令牌之前的预期非限定 id ')'

Compile time error from a Qt file: expected unqualified-id before ')' token

本文关键字:id 编译时错误 文件 Qt 令牌 来自      更新时间:2023-10-16

将我的项目从Qt4移植到Qt5.1,我从Qt文件中收到此错误:

C:QtQt5.1.15.1.1mingw48_32includeQtGuiqopenglversionfunctions.h:785: error: expected unqualified-id before ')' token
     void (QOPENGLF_APIENTRYP MemoryBarrier)(GLbitfield barriers);
                                           ^

这是定义链:

#define QOPENGLF_APIENTRYP QOPENGLF_APIENTRY *
#define QOPENGLF_APIENTRY APIENTRY
#define APIENTRY WINAPI
#define WINAPI __stdcall

我注意到"MemoryBarrier"令牌存在于libQt5OpenGLExtensionsd.a库中。我是否应该包括它,即使在最初的Qt4项目中没有使用与OpenGL相关的任何内容?

平台:
视窗 7
明吉 4.8
Qt 4.8 --> Qt 5.1

除了 MinGW 4.8.1 中的错误和 io.h 中的 uint64_t 之外,QT 5.2.1 中还有这个错误。我今天在尝试使用 MinGW 5.2.1 编译 QT 4.8.1 时遇到了这个问题,所以我想我也会发布我的解决方案。

我不知道QT的官方修复程序是什么,但是为了我的需求,我是这样做的:

在 src/gui/opengl/qopengl.h 第 49 行中:

// Windows always needs this to ensure that APIENTRY gets defined
#if defined(Q_OS_WIN)
# include <QtCore/qt_windows.h>
#endif

我只是在那里取消定义了窗口内存屏障宏:

// Windows always needs this to ensure that APIENTRY gets defined
#if defined(Q_OS_WIN)
# include <QtCore/qt_windows.h>
# undef MemoryBarrier
#endif

我注意到"内存屏障"令牌存在于 libQt5OpenGLExtensionsd.a library.我是否应该包括它,即使在 原始的Qt4项目没有使用与OpenGL相关的内容?

不,这些不相关。OpenGLExtension是在QtGui之后编译的。

不幸的是,您遇到的是Windows上已经定义了MemoryBarrier(),因此存在冲突,并且qt具有什么。您可以找到官方的Windows文档:

http://msdn.microsoft.com/en-us/library/windows/apps/ms684208(v=vs.85).aspx

我刚刚与QtGui维护者Gunnar讨论了这个问题,我计划向Gerrit提交更改以解决您的问题。

几年前,当我们编写基于QtCore的线程安全单例时,我们在项目中使用了这样的东西:

#if defined __GNUC__ && __GNUC__ >= 4 && __GNUC_MINOR__ >= 4    
#define __MEMBARRIER __sync_synchronize();  
#elif defined _MSC_VER && defined _WIN64    
#define __MEMBARRIER MemoryBarrier();   
#else   
#define __MEMBARRIER
#endif

Qt 可能需要检查 ifdef MINGW/GCC/VERSION 和 undef MemoryBarrier 定义。

编辑:这是大约半年前修复的。有关详细信息,请参阅以下 Gerrit 评论和相应的错误报告:

https://codereview.qt-project.org/#change,68156

https://bugreports.qt.io/browse/QTBUG-34080

因此,更新到Qt 5.2.0,它将起作用。如果做不到这一点,您可以尝试向后移植它。

我遇到了同样的问题。我可以编译和运行,只需注释掉有问题的行:

// void (QOPENGLF_APIENTRYP MemoryBarrier)(GLbitfield barriers);
在文件 C:/Qt/Qt5.1.1/

5.1.1/mingw48_32/include/QtGui/qopenglversionfunctions.h:785

我的应用程序不使用任何OpenGL的东西。让我们希望他们尽快修复它;-)

由于当人们尝试自己构建 QT 库时,接受的答案似乎没有帮助,并且 Laszlo Pap 声称其他解决方案不是一个正确的修复方法,我试图找到一种方法来正确修复它。在谷歌上,我找到了一个帖子,据说MemoryBarrier没有在MingW中实现,并且有一个补丁。

所以我试图将修复程序合并到opengl.h并希望这是正确的方法,因为简单地注释掉这些行可能会导致以后出现问题。

#ifndef QT_NO_OPENGL
// Windows always needs this to ensure that APIENTRY gets defined
#if defined(Q_OS_WIN)
# include <QtCore/qt_windows.h>
#if defined(__MINGW32__) && defined(MemoryBarrier)
#undef MemoryBarrier
__CRT_INLINE void MemoryBarrier(void)
{
    long Barrier = 0;
    __asm__ __volatile__("xchgl %%eax,%0 "
        :"=r" (Barrier));
}
#endif
#endif