【问题标题】:MSVC "error C2099: initializer is not a constant" with value composed of other constants, only on CMSVC“错误C2099:初始化器不是常量”,其值由其他常量组成,仅在C上
【发布时间】:2020-02-16 20:47:31
【问题描述】:

我有一些涉及static const uint64_t 值的代码,我试图将其用作位集。问题是,当我使用 MSVC 编译它时,我收到错误 "initializer is not a constant"。但是,当我使用 MSVC 编译代码并将文件重命名为 .cpp 时,它可以正常工作。另外,如果我在 Windows 10 上使用 gcc 编译它,它也可以正常工作。

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

// A 52 card deck can be represented in a bit set.
typedef uint64_t PokerCardSet;

// individal cards
// -------------------------------
static const PokerCardSet HEARTS_A = (PokerCardSet)1 << 0;
static const PokerCardSet HEARTS_2 = (PokerCardSet)1 << 1;
static const PokerCardSet HEARTS_3 = (PokerCardSet)1 << 2;
static const PokerCardSet HEARTS_4 = (PokerCardSet)1 << 3;
static const PokerCardSet HEARTS_5 = (PokerCardSet)1 << 4;
static const PokerCardSet HEARTS_6 = (PokerCardSet)1 << 5;
static const PokerCardSet HEARTS_7 = (PokerCardSet)1 << 6;
static const PokerCardSet HEARTS_8 = (PokerCardSet)1 << 7;
static const PokerCardSet HEARTS_9 = (PokerCardSet)1 << 8;
static const PokerCardSet HEARTS_10 = (PokerCardSet)1 << 9;
static const PokerCardSet HEARTS_J = (PokerCardSet)1 << 10;
static const PokerCardSet HEARTS_Q = (PokerCardSet)1 << 11;
static const PokerCardSet HEARTS_K = (PokerCardSet)1 << 12;

static const PokerCardSet HEARTS_SUIT = HEARTS_A |
                                        HEARTS_2 |
                                        HEARTS_3 |
                                        HEARTS_4 |
                                        HEARTS_5 |
                                        HEARTS_6 |
                                        HEARTS_7 |
                                        HEARTS_8 |
                                        HEARTS_9 |
                                        HEARTS_10 |
                                        HEARTS_J |
                                        HEARTS_Q |
                                        HEARTS_K;

我认为应该没问题的是,HEARTS_SUIT 仅由其他常量组成。所以我不确定为什么我只用 MSVC 得到这个并将它编译为 C 文件。

这是我得到的确切错误

poker.c(69): error C2099: initializer is not a constant

第 69 行是 HEARTS_SUIT 行,但我删除了一些其他出现相同错误的代码,以便更快地阅读和理解。

我的 MSVC 版本是:

Microsoft (R) C/C++ Optimizing Compiler Version 19.16.27032.1 for x64

对于 MSVC 和 C 有没有办法解决这个问题?还是我必须将卡值切换为宏?

【问题讨论】:

  • stackoverflow.com/questions/30962512/…。这是 GCC 的“许可”行为并且严格不符合。请注意,MSVC 上的 C 编译是 ISO C90 - 虽然这不是这里的具体问题,但会导致大量现代 C 代码在任何情况下都无法编译。
  • @Clifford 是有道理的,但为什么它可以与具有相同代码的 .cpp 文件的 MSVC 一起使用? MSVC 是否使用比 C 更高的默认 C++ 标准?
  • 因为C++是不同的语言,两者的const语义不同。

标签: c visual-c++


【解决方案1】:

来自cppreference 网站(尽管在他们关于C 语言的部分中):

const 语义仅适用于左值表达式;每当一个 const 左值表达式用于不需要左值的上下文中, 它的 const 限定符丢失(请注意 volatile 限定符,如果存在, 没有丢失)。

并且,来自实际 C11 Standard(第 6.7.3 节):

与限定类型相关的属性仅对 左值表达式。

在你的表达中:

static const PokerCardSet HEARTS_SUIT = HEARTS_A |
...

HEARTS_A 不是必须是左值,因此const 限定符丢失。

编辑:请注意,在C++ 中,没有这样的“限定符丢失”(无论使用什么版本的标准)。此外,正如 Clifford 的评论中所指出的,以及在他的链接 Stack Overflow discussion 中所讨论的,gcc 编译器在这方面是不合格的。

【讨论】:

  • 这并没有回答为什么这适用于 GCC 而不是 MSVC 编译器的问题。 (Windows 上的 gcc)
  • 同样丢失const 限定符是另一个编译器错误docs.microsoft.com/en-us/cpp/error-messages/compiler-errors-2/…
  • @JoshWeinstein 我添加了一个“编辑”部分以(希望)澄清您的担忧,以及您和其他人在问题中提出的问题。
  • 这很公平。无论如何,这足以保证我在这部分项目中使用 C++
猜你喜欢
  • 1970-01-01
  • 2020-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多