我在我的c++项目中有一个遗留的头文件,已知是好的。它在代码库的各个地方都工作过,没有问题。
它确实拖进了很多其他的标题,我认为这可能是问题的一部分:
/* legacy.h: */
#include "A.h"
#include "B.h"
// (Some definitions I need)
/* A.h: */
#include "C.h" // The rabbit hole continues for another few layers
/* B.h */
#include <windows.h>
#include "D.h" // Again, this also pulls in more things
我在这个项目中写了一个新模块,它也已经工作了好几个星期了:
/* module.h */
// Status codes for new module
struct Status {
enum Enum
{
ALL_GOOD = 0,
ERROR
};
};
/* module.cpp */
#include "module.h"
// (Code that previously didn't require the legacy header)
今天,我做了一个相对较小的添加,需要拉入遗留头文件。突然之间,没有任何东西可以编译!我得到了数百个令人困惑的语法错误,例如:
error C2143:语法错误:'constant'前面缺少'}'
奇怪的是,这些错误将在module.h或module.cpp中的不同行开始,这取决于我尝试使用头文件的顺序。
最糟糕的是,这个问题似乎与我在module.cpp中的新代码没有任何关系。见鬼,我甚至恢复到已经工作了几个星期的版本。这仍然有效,但是当我加入legacy.h时,一切都坏了!
这是怎么回事?我的模块和这个头都知道在其他地方工作得很好,所以它们怎么可能在一起时导致语法错误呢?
您似乎是include chain of legacy.h中某个预处理器宏的受害者。我敢打赌语法错误起源于第一次使用Status::ERROR,正如你的头:
中提到的那样。/* module.h */
// Status codes for new module
struct Status {
enum Enum
{
ALL_GOOD = 0,
ERROR // <- Syntax errors appear here
};
};
在这种情况下,违法者可能是
/* B.h */
#include <windows.h>
我想windows.h有一个宏叫做ERROR.
考虑在枚举定义中使用不同的命名方案,而不是所有的大写,因为定义宏的程序员经常会选择这样的名称。
我有一个类似的情况,例如编译器不理解模板化类的使用:
class SGMarkupElement: public std::enable_shared_from_this<SGMarkupElement> {
与gcc抛出一个语法错误在打开<
,但只有当包括头包含行从一个测试可执行文件-从相应的库实现文件,它编译良好。事实证明,在实现文件中,我包括memory
头,但不是在测试中!在头文件中添加它可以修复所有语法错误。