0

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?

Josh Weinstein
  • 2,788
  • 2
  • 21
  • 38
  • See https://stackoverflow.com/questions/30962512/why-it-is-allowed-to-initialize-static-variable-with-non-const-here. It is "permissive" behaviour of GCC and strictly non-conforming. Note that C compilation on MSVC is ISO C90 - although that is not specifically the issue here, but will lead to a great deal of modern C code not compiling in any case. – Clifford Oct 20 '19 at 16:23
  • @Clifford Makes sense, but why does it work with MSVC with a `.cpp` file with the same code? Does MSVC use a higher default C++ standard than it does for C? – Josh Weinstein Oct 20 '19 at 16:26
  • 2
    Because C++ is a different language, and the semantics of const differ between the two. – Clifford Oct 20 '19 at 16:58

1 Answers1

0

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.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • This does not answer the question why this works on GCC and not on MSVC compiler. (gcc on windows) – Josh Weinstein Oct 20 '19 at 18:21
  • Also losing the `const` qualifier is a different compiler error https://learn.microsoft.com/en-us/cpp/error-messages/compiler-errors-2/compiler-error-c3848?view=vs-2019 – Josh Weinstein Oct 20 '19 at 18:23
  • @JoshWeinstein I've added an 'EDIT' section to (hopefully) clarify your concerns, as well as the comments you and others made in the question. – Adrian Mole Oct 20 '19 at 18:47
  • 1
    that's fair. This is enough to warrant me going with c++ for this part of my project anyways – Josh Weinstein Oct 20 '19 at 19:09