缘起
最近,项目里出现了一个奇怪的编译错误。乍看错误提示,真有丈二的和尚,摸不着头脑的感觉。解决之后,又是这么的合情合理。具体是什么样的问题呢?一起来看看吧。
说明: 实际项目中的错误隐藏的更深,完全没有相关的错误提示。因为不方便用项目代码演示,准备了一个简单的例子,大家可以新建一个控制台工程,并把下面的代码粘贴到对应的文件里。
示例代码简介
示例代码比较简单,共有五个关键文件,加起来不到 40
行代码。大家可以先观察一下代码,思考编译是否会遇到问题。
// NameCollisionDemo.cpp
#include "ModifyInfoTest.h"
int wmain(int argc, wchar_t* argv[])
{
Test();
return 0;
}
// ModifyInfo.h
#pragma once
class CModifyInfo
{
public:
enum class eSource { None = 0, BayWindow, Beam };
CModifyInfo(eSource source_) : source(source_) {}
eSource source;
};
// ModifyInfoTest.h
#pragma once
#include "ModifyInfo.h"
#include "UiMacros.h"
static void Test()
{
CModifyInfo info1(CModifyInfo::eSource::BayWindow);
CModifyInfo info2(CModifyInfo::eSource::Beam);
}
// UiMacros.h
#pragma once
#include "BayWindowUiMacros.h"
// BayWindowUiMacros.h
#pragma once
#define BayWindow "Ui.BayWindow"
初识错误
用 vs
打开工程后,编译,报错如下:

大家能从图中得到什么信息呢?
第一行提示
error C2059: syntax error : '::'
。语法错误?第二行提示
error C2589: 'string' : illegal token on right side of '::'
在::
右侧有非法符号?第三行提示
IntelliSense: expected an identifier
。期待一个标识符?
注意:第三行是 IntelliSense
提示的,不是真正意义上的错误。IntelliSense
提示的错误对是否能成功编译没有影响。注意看图标,不是 大红叉
。第三行给出了出错文件(ModifyInfoTest.h
)及行号( 6
),列号 45
。书中暗表,这个提示是最接近出错地点的。
关键的悬浮提示
对照代码仔细检查,没问题啊。BayWindow
确实在 SourceType
中定义了,大小写也没问题。使用 Visual AssistX
的快捷键 alt + g
能正常跳转到定义。这是什么情况?如果我们把鼠标放到 BayWindow
上,有可能会看到下图中的提示:

Oops
,怎么 BayWindow
变成了一个宏?应该是在编译到这条语句前,遇到了一个名字为 BayWindow
的宏。我们接下来的任务是找到这个宏是在哪里定义的,又为什么会出现在这条语句前。
说明: 在实际项目