如何找到C++编译器认为定义为常量的东西

How do I find something that the C++ compiler thinks is defined as a constant?

本文关键字:定义 常量 何找 C++ 编译器      更新时间:2023-10-16

我在尝试构建应用程序时报告了以下错误:

  • 错误C2143:语法错误:"constant"之前缺少"}"
  • 错误C2143:语法错误:缺少";"在"常量"之前
  • 错误C2059:语法错误:"常量"

对于以下代码:

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是其中一个窗口API头<windi.h>中的#define d(到数字1)。这就是使编译器感到困惑的地方。

您可以#undef它,如果不需要它,可以删除<windows.h>,或者重命名您的枚举。

您在一个包含的文件中的某个位置以该名称定义了一个宏;检查它们。更简单的方法是检查预处理器的输出。

如果使用GCC,请使用-E标志在预处理阶段结束后停止。对于VC++编译器,您应该使用/E和/或/P。请参阅在Visual Studio中预处理后如何查看C/C++源文件?详细信息。


通常,约定是以大写字母命名宏;这也适用于枚举,如果使用C++03的(普通)枚举。一个更好的选择是使用C++11的强类型、作用域枚举。

每个条目的名称可以是Pascal大小写的,通过枚举的名称装饰,它们变得非常可读的Adjustment::Absolute,而不是旧的、无范围的枚举的ABSOLUTE。这不是很可读,因为读者可能会将自己与wingdi.h声明的宏混淆(正如Bathsheba所指出的)。除了可读性之外,它还避免了污染封闭的命名空间。

如果您使用的是visual c++编译器和#include,则应该会出现此错误。在windows.h中,文件#include<wingdi.h>包含在内,在wingdi.h中您可以找到

/* Coordinate Modes */
#define ABSOLUTE            1
#define RELATIVE            2

因此出现了错误。

如何找到C++编译器认为定义为常量的东西?

如果您的编译器不愿意生成有用的消息(通常它会打印之前定义的术语),或者如果您怀疑自己是WinAPI标头中宏voodoo的受害者。。。

选择性地注释掉代码行,然后重新编译以确定问题所在。如果注释掉一行,然后编译程序,则行就是问题的根源。如果你的代码块很大,可以进行"二进制搜索"——先注释掉一整块,然后注释掉一半,这样你就可以很快缩小问题范围。

在IDE中,您通常可以将鼠标悬停在项目上查看它的定义位置,或者按键或使用上下文菜单"跳转到定义"。

除此之外,您还可以调查预处理器的输出。


并且当它发生变化时,不能选择性地注释出要测试的头,因为新的编译器警告列表太繁重了,无法通过工作

制作一个空白的*.cpp文件,并将有问题的定义复制到其中,直到您破坏它。这将使您能够精确定位问题。

在您自己的*.h文件中始终只包含最少量必要的头文件是一种很好的做法,最好完全避免特定于操作系统的头文件,尽管在这种情况下这是不可能的。

在您的特定场景中,另一个好的选择是更改枚举值的命名样式。通常,ALL_UPPERCASE仅用于宏(宏定义和宏常量)。此规则的一个显著例外是在Windows标头中定义的minmax宏(它们可以被禁用)。因为您在enum中使用了它,所以与特定于操作系统的定义发生了冲突。对于枚举,我将使用与常量和局部变量相同的命名约定。