来自 Qt 文件的编译时错误:在 ')' 标记之前预期的 unqualified-id

Posted

技术标签:

【中文标题】来自 Qt 文件的编译时错误:在 \')\' 标记之前预期的 unqualified-id【英文标题】:Compile time error from a Qt file: expected unqualified-id before ')' token来自 Qt 文件的编译时错误:在 ')' 标记之前预期的 unqualified-id 【发布时间】:2013-09-11 11:16:59 【问题描述】:

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

C:\Qt\Qt5.1.1\5.1.1\mingw48_32\include\QtGui\qopenglversionfunctions.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 MinGW 4.8 Qt 4.8 --> Qt 5.1

【问题讨论】:

【参考方案1】:

除了bug in MinGW 4.8.1 with uint64_t in io.h,QT 5.2.1 中还有这个。我今天在尝试使用 MinGW 4.8.1 编译 QT 5.2.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 MemoryBarrier 宏的定义:

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

【讨论】:

这不是修复它的正确方法 - 事实上,它可能会破坏其他情况 - 而QT 是一个不同的项目。有关详细信息,请阅读标签。此外,它最好在用户应用程序代码中解决,而不需要重新构建 Qt 本身,因为它是一个漫长的过程。 不幸的是,如果您的应用程序项目使用构建 QT 的不同版本的 MingGW,或者您想要不同的线程(posix 与 win32 线程),您通常确实需要重建 QT。这就是我必须重建它的原因。 @LaszloPapp 同意,但如果它可以在用户应用程序中解决而不是更改 QT 源代码会更好,但我发布的解决方案适用于所有版本的 MinGW。对于所有版本的 MinGW,QT 确实需要对此进行更好的修复。【参考方案2】:

我注意到“MemoryBarrier”令牌存在于 libQt5OpenGLExtensionsd.a 库。我应该包括它,即使在 原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 并取消定义 MemoryBarrier 的定义。

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

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

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

所以,更新到 Qt 5.2.0 就可以了。如果做不到这一点,您可以尝试向后移植它。

【讨论】:

仅作记录,今天发布的 5.2.0 版本仍然存在此问题。 @MassimoCallegari:是的,显然我们没有时间在上游修复它。 虽然这个答案可能很有趣,但它并没有真正的帮助,因为没有人知道这必须应用在哪里。 @LaszloPapp,“看不见的代码”?这是官方的 QT 5.2 源下载,不应该是一些“未知代码”。考虑到这已经知道了几个月 bugreports.qt-project.org/browse/QTBUG-34044 我本来希望即使最新版本可能没有包含修复程序,也应该有适当的修复描述。 @LaszloPapp 不,它不是固定的。还记得我尝试构建 5.3.0 来进行串行设备序列号测试吗?我被这个 MemoryBarrier 的东西抓狂了。恐怕即使在 5.3.0 上它仍然存在【参考方案3】:

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

// void (QOPENGLF_APIENTRYP MemoryBarrier)(GLbitfield barriers);

在文件 C:/Qt/Qt5.1.1/5.1.1/mingw48_32/include/QtGui/qopenglversionfunctions.h:785

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

【讨论】:

【参考方案4】:

由于当人们尝试自己构建 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

【讨论】:

上游已经修复:codereview.qt-project.org/#change,68156我更新了我的回复。

以上是关于来自 Qt 文件的编译时错误:在 ')' 标记之前预期的 unqualified-id的主要内容,如果未能解决你的问题,请参考以下文章

链接来自另一个文件的函数时,Qt 上出现错误 LNK 2019 [重复]

qt的编译错误

QT5.8+VS2015 开发时遇到的坑

gcc 错误“预期 ')' 在 '[' 标记”之前

在vs2010编译qt程序时就会出现错误无法打开文件"Qt5Cored.lib"

QT的MyQL编译