【问题标题】:How come the compiler thinks this variable isn't constant?编译器怎么会认为这个变量不是常量?
【发布时间】:2011-05-26 08:54:56
【问题描述】:

这是我的代码:

int main()
{
 const int LEN = 5;
 int x[LEN];
}

VS10 说:

错误 C2057:预期常量 表达

错误 C2466:无法分配数组 大小为 0

错误 C2133:“x”:未知大小

我什至尝试了此页面中的代码,但它给出了同样的问题(我注释了给出错误的代码,并取消了正确的注释): http://msdn.microsoft.com/en-us/library/eff825eh%28VS.71%29.aspx

如果我尝试使用糟糕的编译器,我会认为这是编译器中的错误,但它是 VS2010!

【问题讨论】:

  • 检查 LEN 是否没有在某处#定义?
  • 我的问题是你为什么不为此使用#define
  • @William: #defines 不是定义常量的好方法,因为它们使用预处理器并且缺少输入信息等;较新的语言通常甚至没有等价物。在大多数情况下,像这样的常量是更好的做法。
  • @sje397 我确定源代码中没有任何#define。
  • 所有#defines 都是全局的,这就是它们不好的原因。有一天你会想在本单元下面的某个地方#define 另一个 LEN。当一个 .cpp 单元中的所有#defines 都不是什么大问题,但仍然很烦人。

标签: c++ c compiler-construction compiler-errors


【解决方案1】:

您可能已经使用 .c 扩展名编译了您的代码。 MS Visual C 不支持 C99。在 C89 中,数组的大小必须是常量表达式。 const 限定变量在 C 中不是 constants。它们不能用于需要真正的 constant 的地方。

另请阅读 AndreyT 的 this excellent post

尝试使用 .cpp 扩展名保存文件。

【讨论】:

  • 在 gcc 中为我工作,无论我指定什么 C 方言。但我认为你可能正在做一些调整 Visual Studio 的事情。
  • @Jon : gcc 支持 C99 并且可变长度数组是 C99 的一部分,因此代码在 gcc 中工作。该代码在 C99 和 C++ 中有效。
  • @Jon 与-ansi,GCC 给出warning: ISO C90 forbids variable-size array ‘x’
【解决方案2】:

根据http://msdn.microsoft.com/en-us/library/3ffb821x.aspx,“用常量表达式初始化的声明为 const 的值”在数组边界中是合法的,因此这是有效的 C++ 代码。

因此,这要么是编译器错误,要么是某个地方的#define 奇怪的东西。正如 sje397 的评论所暗示的,尝试使用 LEN 以外的其他名称作为长度?另外,这实际上是您的整个代码,还是标头也被#included 了?

编辑添加:此外,正如其他人所指出的那样,如果您将其编译为 C,那么这是有效的 C++ 代码这一事实当然无关紧要。

【讨论】:

  • 这更像是一个未实现的功能,而不是一个严重的错误。当我将代码从 G++ 移植到其他编译器时,我遇到了同样的问题,不过我不记得是哪一个了。
  • 我认为在 C++ 中这是一个严重的错误(常量表达式实际上应该是一个常量表达式是非常基本的),而在 C99 中,该错误将是一个未实现的功能变长数组。但这是一个公平的观点。
【解决方案3】:

你也可以使用

int main()
{
    enum { LEN = 5 };
    int x[LEN];
}

【讨论】:

【解决方案4】:

因为在这种情况下,我可以做到:

int main()
{
    const int LEN = 5;
    int* LENptr = (int*)(&LEN);
    *LENptr = 10;
    int x[LEN];
}

which const is only表示在这段代码中是只读的,而不是编译时常量

【讨论】:

  • 此“示例”表现出未定义的行为,因此您无法从其行为中推断出任何关于该语言的信息。
  • 您可以编写该代码,并且也许可以编译它,但是抛弃指针目标的常量实际上是否意味着它是合法的 C++ 然后更改其值?我不这么认为。如果我在该代码的末尾添加printf("%d\n", LEN);,并使用 g++ 编译并运行它,它会打印 5,而不是 10。我几乎很惊讶它没有段错误。
  • 我刚刚尝试了您的代码(用于科学:),但 LEN 从未改变。所以,也许就像贝利所说的“未定义的行为”。
  • 当然,我意识到原始发布者并没有说明这是 C++ 还是 C,我只是从 C++ 标签中假设它是 C++——我没有看到 C 标签。
  • 在某些平台上肯定会出现段错误。这发生在我身上一次。
猜你喜欢
  • 2013-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-25
  • 2023-01-10
相关资源
最近更新 更多