我如何找到 C++ 编译器认为定义为常量的内容?
How do I find something that the C++ compiler thinks is defined as a constant?
我在尝试构建我的应用程序时报告了以下错误:
- 错误 C2143:语法错误:在 'constant'
之前缺少“}”
- 错误 C2143:语法错误:缺少“;”在 'constant'
之前
- 错误 C2059:语法错误:'constant'
对于以下代码:
namespace oP
{
enum adjustment
{
AUTO_OFF,
AUTO_ONCE,
AUTO_CONTINUOUS,
AUTO_SEMI,
ABSOLUTE, // The line that the errors point to.
NUDGE
};
}
小写 "absolute" 构建正常,如果我拼写错误 ABSOLUTE 则构建没有错误。
我搜索了我的整个代码库,没有其他地方使用术语 "ABSOLUTE"。
我调查了没有此更改的构建工件,但我在其中找不到任何对 ABSOLUTE 的引用。
有没有人指出问题所在或如何调试?
谢谢
ABSOLUTE
是 #define
d(到数字 1)在 windows API headers <windi.h>
之一。这就是让编译器感到困惑的地方。
您可以 #undef
它,如果不需要它,请删除 <windows.h>
,或者重命名您的枚举。
您在其中一个包含的文件中的某处以该名称定义了一个宏;检查它们。更简单的方法是检查预处理器的输出。
如果您使用 GCC,请使用 -E
标志在预处理阶段后停止。使用 VC++ 编译器,您应该使用 /E
and/or /P
。有关详细信息,请参阅 How do I see a C/C++ source file after preprocessing in Visual Studio?。
通常惯例是全部大写命名宏;这也适用于枚举,如果 你使用 C++03 的(普通)枚举。更好的选择是使用 C++11 的强类型 scoped enumerations.
每个条目的名称都可以是 Pascal 大小写,并且通过枚举的名称修饰,它们变得非常易读 Adjustment::Absolute
,而不是旧的、无范围的枚举 ABSOLUTE
。这不是很可读,因为 reader 可能会将自己与 wingdi.h
声明的宏混淆(正如 Bathsheba 指出的那样)。除了可读性之外,它还避免了污染封闭的命名空间。
你正在使用 visual c++ 编译器和 #include 那么你应该会得到这个错误。在 windows.h 中包含文件 #include < wingdi.h>,在 wingdi.h 中你会发现
/* Coordinate Modes */
#define ABSOLUTE 1
#define RELATIVE 2
因此发生错误。
How do I find something that the C++ compiler thinks is defined as a constant?
如果您的编译器不愿意生成有用的消息(通常它会在之前定义术语的地方打印)或者如果您怀疑自己成为了 WinAPI 宏巫术的受害者 headers...
有选择地注释掉代码行并重新编译以查明问题所在。
如果您注释掉一行并且您的程序在那之后编译,那么 that 行就是问题的根源。如果您的代码块很大,请执行 "binary search" - 注释掉整个块,然后是一半,这样您可以快速缩小问题范围。
在 IDE 中,您通常可以将鼠标悬停在项目上以查看它的定义位置,或者按一个键或使用上下文菜单 "jump to definition"。
除此之外,您还可以研究预处理器输出。
and can't selectively comment out headers to test when it changes - since the new list of compiler warnings would be too onerous to work through
创建一个空白的 *.cpp 文件并将有问题的定义复制到其中,直到你破坏它。这将使您能够查明问题所在。
在您自己的 *.h 文件中始终只包含必要的最小集合 headers 是一个很好的做法,最好完全避免 OS-specific headers,尽管那不是在这种情况下真的有可能。
在您的特定情况下,另一个不错的选择是更改枚举值的命名样式。通常 ALL_UPPERCASE
只为宏保留(宏定义和宏常量)。此规则的一个值得注意的例外是 Windows headers 中定义的 min
和 max
宏(它们可以被禁用)。因为您在 enum
中使用了它,所以您与 OS-specific 定义发生冲突。我会对枚举使用与常量和局部变量相同的命名约定。
我在尝试构建我的应用程序时报告了以下错误:
- 错误 C2143:语法错误:在 'constant' 之前缺少“}”
- 错误 C2143:语法错误:缺少“;”在 'constant' 之前
- 错误 C2059:语法错误:'constant'
对于以下代码:
namespace oP
{
enum adjustment
{
AUTO_OFF,
AUTO_ONCE,
AUTO_CONTINUOUS,
AUTO_SEMI,
ABSOLUTE, // The line that the errors point to.
NUDGE
};
}
小写 "absolute" 构建正常,如果我拼写错误 ABSOLUTE 则构建没有错误。
我搜索了我的整个代码库,没有其他地方使用术语 "ABSOLUTE"。 我调查了没有此更改的构建工件,但我在其中找不到任何对 ABSOLUTE 的引用。
有没有人指出问题所在或如何调试?
谢谢
ABSOLUTE
是 #define
d(到数字 1)在 windows API headers <windi.h>
之一。这就是让编译器感到困惑的地方。
您可以 #undef
它,如果不需要它,请删除 <windows.h>
,或者重命名您的枚举。
您在其中一个包含的文件中的某处以该名称定义了一个宏;检查它们。更简单的方法是检查预处理器的输出。
如果您使用 GCC,请使用 -E
标志在预处理阶段后停止。使用 VC++ 编译器,您应该使用 /E
and/or /P
。有关详细信息,请参阅 How do I see a C/C++ source file after preprocessing in Visual Studio?。
通常惯例是全部大写命名宏;这也适用于枚举,如果 你使用 C++03 的(普通)枚举。更好的选择是使用 C++11 的强类型 scoped enumerations.
每个条目的名称都可以是 Pascal 大小写,并且通过枚举的名称修饰,它们变得非常易读 Adjustment::Absolute
,而不是旧的、无范围的枚举 ABSOLUTE
。这不是很可读,因为 reader 可能会将自己与 wingdi.h
声明的宏混淆(正如 Bathsheba 指出的那样)。除了可读性之外,它还避免了污染封闭的命名空间。
你正在使用 visual c++ 编译器和 #include 那么你应该会得到这个错误。在 windows.h 中包含文件 #include < wingdi.h>,在 wingdi.h 中你会发现
/* Coordinate Modes */
#define ABSOLUTE 1
#define RELATIVE 2
因此发生错误。
How do I find something that the C++ compiler thinks is defined as a constant?
如果您的编译器不愿意生成有用的消息(通常它会在之前定义术语的地方打印)或者如果您怀疑自己成为了 WinAPI 宏巫术的受害者 headers...
有选择地注释掉代码行并重新编译以查明问题所在。 如果您注释掉一行并且您的程序在那之后编译,那么 that 行就是问题的根源。如果您的代码块很大,请执行 "binary search" - 注释掉整个块,然后是一半,这样您可以快速缩小问题范围。
在 IDE 中,您通常可以将鼠标悬停在项目上以查看它的定义位置,或者按一个键或使用上下文菜单 "jump to definition"。
除此之外,您还可以研究预处理器输出。
and can't selectively comment out headers to test when it changes - since the new list of compiler warnings would be too onerous to work through
创建一个空白的 *.cpp 文件并将有问题的定义复制到其中,直到你破坏它。这将使您能够查明问题所在。
在您自己的 *.h 文件中始终只包含必要的最小集合 headers 是一个很好的做法,最好完全避免 OS-specific headers,尽管那不是在这种情况下真的有可能。
在您的特定情况下,另一个不错的选择是更改枚举值的命名样式。通常 ALL_UPPERCASE
只为宏保留(宏定义和宏常量)。此规则的一个值得注意的例外是 Windows headers 中定义的 min
和 max
宏(它们可以被禁用)。因为您在 enum
中使用了它,所以您与 OS-specific 定义发生冲突。我会对枚举使用与常量和局部变量相同的命名约定。