我在VS2012中有一个使用预编译头文件(不确定是否相关)的Qt项目,它编译并且工作正常。但是当我尝试在QtCreator中编译同一个项目时,它会显示错误。首先 - 两个项目彼此对应,之前已经正确配置(它们编译和工作得很好)。但是,在对代码进行最新更改后,出现了问题。
错误:
pch.h:34: error:C2084: function 'void handleExceptionByShowingMessage(std::exception &)' already has a body
main.cpp:16: error:C3861: 'handleExceptionByShowingMessage': identifier not found
这些行继续使用pch.h中定义的另一个函数(内联行)以及一些cpp文件。但所有错误都是类比的。
来自pch.h
:
inline void handleExceptionByShowingMessage(std::exception &e)
{
QMessageBox msgBox;
msgBox.setText(QString::fromUtf16((ushort*)e.what()));
msgBox.setStandardButtons(QMessageBox::Discard);
msgBox.setIcon(QMessageBox::Warning);
int ret = msgBox.exec();
}
我不粘贴来自cpp
文件的函数调用,因为它只是常规使用。所有cpp
文件都正确地包含pch.h
(第一行代码),正如我所说的 - 完全相同的代码和文件结构在VS2012中工作(我相信,其编译器,QtCreator实际上使用了......)。
如果您需要更多代码/信息,请告知我们。
更新
是的,所有标头都有#pragma once
。 有趣的通知 - 当我将这两个函数定义移动到虚拟头文件并将其包含在pch.h
中时,项目编译正常。
答案 0 :(得分:2)
#pragma once
仅阻止包含指令的文件多次被包含。预编译头文件pch.h
在加载预编译头时包含,第二次编译文件时包含。 #pragma
指令将它们视为单独的文件,因此在此上下文中不起作用。
pch.h
文件(或stdafx.h
)是一种优化,理想情况下不应包含源代码,只能包含#includes
其他头文件。这样,包括它好几次都不会成为问题。
另一种解决方案是使用包含保护(#ifndef PCH #define PCH #endif
),这将阻止文件被多次包含。
答案 1 :(得分:1)
如果代码在标头中,您可以尝试static inline
。
我不知道为什么inline
并不意味着static
,但我也在不久前发现了这一点。