views:

413

answers:

5
+3  Q: 

const vs enum in D

Check out this quote from here, towards the bottom of the page. (I believe the quoted comment about consts apply to invariants as well)

Enumerations differ from consts in that they do not consume any space in the final outputted object/library/executable, whereas consts do.

So apparently value1 will bloat the executable, while value2 is treated as a literal and doesn't appear in the object file.

const int value1 = 0xBAD;
enum int value2 = 42;

Back in C++ I always assumed this was for legacy reasons, and old compilers that couldn't optimize away constants. But if this is still true in D, there must be a deeper reason behind this. Anyone know why?

+1  A: 

It sounds like the enum value will be used "inline" in expressions where as the const will actually take storage and any expression referencing it will be loading the value from the memory storage.

This sound similar to the difference between const vs. readonly in C#. The former is a compile-time constant and the later is a run-time constant. This definitely affected versioning of assemblies (since assemblies referencing a readonly would receive a copy at compile time and would not get a change to the value if the referenced assembly was rebuilt with a different value).

chrish
+2  A: 

I think a good compiler/linker should still remove the constant. It's just that with the enum, it's actually guaranteed in the spec. The difference is primarily a matter of semantics. (Also keep in mind that 2.0 isn't complete yet)

FeepingCreature
But that wish assumes that the compiler always have all the relevant source.
larsivi
What if you want to give third-party libraries access to that const variable? What if it is a whole class instance that has been made const?
Marenz
Note I said "compiler/*linker*". Besides, D has to be able to see the value of the variable at compile-time anyway (for constant folding and other things), so there's even less point in physically storing it somewhere - any situation where it'd be required _needs_ the source available anyway. (I'm not aware of any compilers that internally disassemble object code from an earlier run)
FeepingCreature
+3  A: 

Just like in C++, an enum in D seems to be a "conserved integer literal" (edit: amazing, D2 even supports floats and strings). Its enumerators have no location. They are just immaterial as values without identity.

Placing enum is new in D2. It first defines a new variable. It is not an lvalue (so you also cannot take its address). An

enum int a = 10; // new in D2

Is like

enum : int { a = 10 }

If i can trust my poor D knowledge. So, a in here is not an lvalue (no location and you can't take its address). A const, however, has an address. If you have a global (not sure whether this is the right D terminology) const variable, the compiler usually can't optimize it away, because it doesn't know what modules can access that variable or could take its address. So it has to allocate storage for it.

I think if you have a local const, the compiler can still optimize it away just as in C++, because the compiler knows by looking at its scope whether or not anyone is interested in its address or whether everyone just takes its value.

Johannes Schaub - litb
+1  A: 

Your actual question; why enum/const is the same in D as in C++; seems to be unanswered. Sadly there exists no good reason for this choice whatsoever. I believe that this was just an unintentional side effect in C++ that became a de facto pattern. In D the same pattern was needed, and Walter Bright decided that it should be done as in C++ such that those coming from that place would recognize what to do ... In fact, before this rather IMHO silly decision, the keyword manifest was used instead of enum for this usecase.

larsivi
It is unfortunate the `enum` means manifest constant. However, D makes it a point only to change what is expressly broken, everything else follows the established norms for algol languages. I'm sure if you really went all out you could find lots of weird keywords and syntax that could have been done better, eg assignment/equality, return value listed before function name, structure/aggregate, etc.
caspin
+2  A: 

The real purpose of enum being expanded syntactically to support single manifest constants, from what I understand, is that Don Clugston, a D template guru, was doing some crazy stuff with templates. He kept running into long build times, ridiculous compiler memory usage, etc. because the compiler kept creating internal data strucutres for const variables. One key thing about const/immutable variables compared to enums is that const/immutable variables are lvalues and can have their address taken. This means there is some extra overhead for the compiler. This usually doesn't matter, but when you're executing really complicated compile-time metaprograms, even if const variables are optimized away, this is still significant overhead at compile time.

dsimcha