简体   繁体   中英

MSVC “error C2099: initializer is not a constant” with value composed of other constants, only on C

I have some code involving static const uint64_t values I am trying to use as a bitset. The issue is, when I compile it with MSVC, I get the error "initializer is not a constant" . However, when I compile the code with MSVC and rename the file as .cpp , it works fine. Also, If I compile it with gcc on windows 10, it also works fine.

Here is the code:

#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;

What I think should be ok is that, HEARTS_SUIT is composed only of other constants. So I am not sure why I am getting this only with MSVC and compiling it as a C file.

This is the exact error I get

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

line 69 is the HEARTS_SUIT line, but I took away some other code that gets the same error so it's faster to read and comprehend.

My MSVC version is:

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

IS there a way around this for MSVC and C? Or would I have to switch the card values to be macros?

From cppreference website (though in their section on the C language):

const semantics apply to lvalue expressions only; whenever a const lvalue expression is used in context that does not require an lvalue, its const qualifier is lost (note that volatile qualifier, if present, isn't lost).

And, from the actual C11 Standard (Section 6.7.3):

The properties associated with qualified types are meaningful only for expressions that are lvalues.

In your expression:

static const PokerCardSet HEARTS_SUIT = HEARTS_A |
...

HEARTS_A is not required to be an lvalue, so the const qualifier is lost.

EDIT: Note that, in C++ , there is no such "qualifier loss" (whatever version of the Standard is used). Further, as noted in the comment by Clifford , and discussed in the Stack Overflow discussion he links, the gcc compiler is non-conforming in this respect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM