5
const enum Alpha{
    X=9,
    Y=5,
    Z=2
}p;
int main(){
    enum Alpha a,b;
    a= X;
    b= Z;

    p = X;
    p = Y;

    printf("%d",a+b-p); 
    return 0; 
}

Why is p = X and p = Y allowed in MSVC compiler? This code outputs 6. Shouldn't a const value be assigned at initialization and never again?

Johnny Pauling
  • 12,701
  • 18
  • 65
  • 108

3 Answers3

6

That is a bug in the compiler itself. End of the story.

In fact, your little code shows two bugs in the compiler. The first bug is here itself:

const enum Alpha{
    X=9,
    Y=5,
    Z=2
}p;    //declaration of p is ill-formed!

The declaration of p is ill-formed, and thus the compiler should reject this code, because p is declared const but left uninitialized. A const scalar (and pod) type must be initialized in order to be well-formed:

const Alpha q;      //ill-formed (same case is with p in your code)
const Alpha r = X;  //well-formed

For detailed and extensive explanation, see this:

Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851
1

Looks like a bug, indeed.

First of all, global const objects must be initialized when defined, and default-initialization is not an option for enumeration types. According to Paragraph 8.5/6 of the C++11 Standard:

To default-initialize an object of type T means:

— if T is a (possibly cv-qualified) class type (Clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);

— if T is an array type, each element is default-initialized;

— otherwise, no initialization is performed.

If a program calls for the default initialization of an object of a const-qualified type T, T shall be a class type with a user-provided default constructor.

Secondly, a const object cannot be assigned after initialization.

Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
-2

Edited to match consensus that this is a compiler bug.

This works because the compiler erroneously thinks that p is of type Alpha and not const Alpha. If you rewrite this as

enum Alpha{....
} const p;

the compiler will correctly complain that a constant is not being initialized.

error C2734: 'p' : const object must be initialized if not extern
error C3892: 'p' : you cannot assign to a variable that is const

If you assign the constant,

enum Alpha{....
} const p = Y;

and remove the assignment to p, everything compiles and works as expected.

Thomas
  • 4,980
  • 2
  • 15
  • 30
  • *"This works because p is of type `Alpha` and not `const Alpha`"*. THIS IS WRONG. Type of `p` is `const Alpha`, as `const` applies on the variable, not on the enum definition. Also, `const Alpha p` and `Alpha const p` are the exactly same thing! – Nawaz Feb 17 '13 at 17:00
  • I'm not a language lawyer. I'll leave that to the experts. – Thomas Feb 17 '13 at 18:34
  • You don't need to be "language lawyer" or "expert" to know that. A good understanding of C++ declaration is more than enough. – Nawaz Feb 17 '13 at 18:51
  • There is still the bit about the PODness and the default constructor. I can't check whether this should compile, but MSVC does, `enum Alpha {...} const p = Alpha();` and it was not immediately clear (at least to me) that this is different from `enum Alpha{...} p;` – Thomas Feb 17 '13 at 19:11
  • `enum Alpha {...} const p = Alpha();` is absolutely fine, because you're initializing `p`. And the second example `enum Alpha {...} p;` is also fine, because `p` is not `const` in this case, so you can leave it uninitialized. – Nawaz Feb 17 '13 at 19:14
  • sorry, forgot a const. meant to write: is different from `enum Alpha{...} const p;`, – Thomas Feb 17 '13 at 19:18
  • That is ill-formed, as `p` is `const` but left uninitialized. :-) – Nawaz Feb 17 '13 at 19:24
  • Yet something like `const struct D{ int a; } d;` compiles and not ill-formed because it is nonPOD and default initialized. That is what I was refering to. – Thomas Feb 17 '13 at 19:32
  • That too is ill-formed. Which version of which compiler are you using? – Nawaz Feb 17 '13 at 19:34
  • That is MSVC `11.0.51106.01 Update 1`. But it compiles on the `10.0.40219.1 SP1Rel` as well. – Thomas Feb 17 '13 at 19:46
  • That must be a bug in MSVC. [GCC is right](http://stacked-crooked.com/view?id=4e60a5b5547c8a93692ea673f3bd5b11) in saying that the code is ill-formed. – Nawaz Feb 17 '13 at 19:48