www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Manifest constants: why enum instead of invariant?

reply Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
Picking up and idea which had crossed my mind, and that Oskar Linde 
briefly mentioned on the const debacle thread 
(news://news.digitalmars.com:119/fsirc9$2hll$1 digitalmars.com):

Why do we need enum instead of invariant to declare manifest constants?

(I have the feeling that this has been discussed before in the manifest 
constants debate but I can't remember it nor find it)

An invariant variable offers all the power than enum does for manifest 
constants. The only difference of enum's manifest constants is that they 
are not an lvalue (their address cannot be taken). But that's a 
*restriction*, it's not a useful property.

The only possible advantage I see is that of optimization: manifest 
constants do not take up space. But that *hardly* seems significant: 
manifest constants are usually numeric, and thus occupy about 2-4 bytes 
each. Even if they are many, in total they are not going to occupy that 
much space. A string literal can easily occupy as much space as several 
manifest constants, and they are likely going to be many string literals 
abound.

-- 
Bruno Medeiros - Software Developer, MSc. in CS/E graduate
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Apr 27 2008
next sibling parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Bruno Medeiros wrote:
 Picking up and idea which had crossed my mind, and that Oskar Linde 
 briefly mentioned on the const debacle thread 
 (news://news.digitalmars.com:119/fsirc9$2hll$1 digitalmars.com):
 
 Why do we need enum instead of invariant to declare manifest constants?
 
 (I have the feeling that this has been discussed before in the manifest 
 constants debate but I can't remember it nor find it)
 
 An invariant variable offers all the power than enum does for manifest 
 constants. The only difference of enum's manifest constants is that they 
 are not an lvalue (their address cannot be taken). But that's a 
 *restriction*, it's not a useful property.
 
 The only possible advantage I see is that of optimization: manifest 
 constants do not take up space. But that *hardly* seems significant: 
 manifest constants are usually numeric, and thus occupy about 2-4 bytes 
 each. Even if they are many, in total they are not going to occupy that 
 much space. A string literal can easily occupy as much space as several 
 manifest constants, and they are likely going to be many string literals 
 abound.
 

The space *is* a significant problem apparently. There have been many complaints about the size added to an exe simply by linking in early versions of the Windows headers because of all the constants they define. But I suppose you could also look at that and say "we need to fix the linker & optimizer" instead of "we need to fix the language". --bb
Apr 27 2008
parent reply Don <nospam nospam.com.au> writes:
Bill Baxter wrote:
 Bruno Medeiros wrote:
 Picking up and idea which had crossed my mind, and that Oskar Linde 
 briefly mentioned on the const debacle thread 
 (news://news.digitalmars.com:119/fsirc9$2hll$1 digitalmars.com):

 Why do we need enum instead of invariant to declare manifest constants?

 (I have the feeling that this has been discussed before in the 
 manifest constants debate but I can't remember it nor find it)

 An invariant variable offers all the power than enum does for manifest 
 constants. The only difference of enum's manifest constants is that 
 they are not an lvalue (their address cannot be taken). But that's a 
 *restriction*, it's not a useful property.

 The only possible advantage I see is that of optimization: manifest 
 constants do not take up space. But that *hardly* seems significant: 
 manifest constants are usually numeric, and thus occupy about 2-4 
 bytes each. Even if they are many, in total they are not going to 
 occupy that much space. A string literal can easily occupy as much 
 space as several manifest constants, and they are likely going to be 
 many string literals abound.

The space *is* a significant problem apparently. There have been many complaints about the size added to an exe simply by linking in early versions of the Windows headers because of all the constants they define. But I suppose you could also look at that and say "we need to fix the linker & optimizer" instead of "we need to fix the language".

Indeed. Manifest constants are required primarily as a workaround for the linker; the linker should be able to discard them. In practice, most of the time, invariant will probably be used anyway. I think much of the furore about using enum for constants fails to recognise how minor the feature is. IMHO, the unfortunate thing about using enum for manifest constants is that it destroys any chance of better enums.
Apr 28 2008
parent reply Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
Don wrote:
 Bill Baxter wrote:
 Bruno Medeiros wrote:
 Picking up and idea which had crossed my mind, and that Oskar Linde 
 briefly mentioned on the const debacle thread 
 (news://news.digitalmars.com:119/fsirc9$2hll$1 digitalmars.com):

 Why do we need enum instead of invariant to declare manifest constants?

 (I have the feeling that this has been discussed before in the 
 manifest constants debate but I can't remember it nor find it)

 An invariant variable offers all the power than enum does for 
 manifest constants. The only difference of enum's manifest constants 
 is that they are not an lvalue (their address cannot be taken). But 
 that's a *restriction*, it's not a useful property.

 The only possible advantage I see is that of optimization: manifest 
 constants do not take up space. But that *hardly* seems significant: 
 manifest constants are usually numeric, and thus occupy about 2-4 
 bytes each. Even if they are many, in total they are not going to 
 occupy that much space. A string literal can easily occupy as much 
 space as several manifest constants, and they are likely going to be 
 many string literals abound.

The space *is* a significant problem apparently. There have been many complaints about the size added to an exe simply by linking in early versions of the Windows headers because of all the constants they define.


Around how many bytes are we talking about here, just to get a concrete idea, does anyone know? I'm not familiar with the windows headers nor their D bindings, although I recently checked some of the windows d headers and there were many manifest constants. But I still don't know if their size would amount to something that significant. If for example, you have a cmd line program that prints one page of it's syntax/usage, just that single string would occupy the same space as 400 manifest constants or more.
 But I suppose you could also look at that and say "we need to fix the 
 linker & optimizer" instead of "we need to fix the language".

Indeed. Manifest constants are required primarily as a workaround for the linker; the linker should be able to discard them. In practice, most of the time, invariant will probably be used anyway. I think much of the furore about using enum for constants fails to recognise how minor the feature is. IMHO, the unfortunate thing about using enum for manifest constants is that it destroys any chance of better enums.

Yes, if that's just the case, then it's a very minor feature indeed, both because it arises in an uncommon situation (using windows headers), it could be fixed by the compiler/linker. -- Bruno Medeiros - Software Developer, MSc. in CS/E graduate http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Apr 29 2008
parent reply Don <nospam nospam.com.au> writes:
Bruno Medeiros wrote:
 Don wrote:
 Bill Baxter wrote:
 Bruno Medeiros wrote:
 Picking up and idea which had crossed my mind, and that Oskar Linde 
 briefly mentioned on the const debacle thread 
 (news://news.digitalmars.com:119/fsirc9$2hll$1 digitalmars.com):

 Why do we need enum instead of invariant to declare manifest constants?

 (I have the feeling that this has been discussed before in the 
 manifest constants debate but I can't remember it nor find it)

 An invariant variable offers all the power than enum does for 
 manifest constants. The only difference of enum's manifest constants 
 is that they are not an lvalue (their address cannot be taken). But 
 that's a *restriction*, it's not a useful property.

 The only possible advantage I see is that of optimization: manifest 
 constants do not take up space. But that *hardly* seems significant: 
 manifest constants are usually numeric, and thus occupy about 2-4 
 bytes each. Even if they are many, in total they are not going to 
 occupy that much space. A string literal can easily occupy as much 
 space as several manifest constants, and they are likely going to be 
 many string literals abound.

The space *is* a significant problem apparently. There have been many complaints about the size added to an exe simply by linking in early versions of the Windows headers because of all the constants they define.


Around how many bytes are we talking about here, just to get a concrete idea, does anyone know? I'm not familiar with the windows headers nor their D bindings, although I recently checked some of the windows d headers and there were many manifest constants. But I still don't know if their size would amount to something that significant. If for example, you have a cmd line program that prints one page of it's syntax/usage, just that single string would occupy the same space as 400 manifest constants or more.

void main() {} --> 79kB exe. ------- import win32.core; void main() {} --> 108kB exe. So it looks like it's less than 32K. Less than 40% of the size of the phobos runtime and gc. And a good linker would remove it ALL.
 
 But I suppose you could also look at that and say "we need to fix the 
 linker & optimizer" instead of "we need to fix the language".

Indeed. Manifest constants are required primarily as a workaround for the linker; the linker should be able to discard them. In practice, most of the time, invariant will probably be used anyway. I think much of the furore about using enum for constants fails to recognise how minor the feature is. IMHO, the unfortunate thing about using enum for manifest constants is that it destroys any chance of better enums.

Yes, if that's just the case, then it's a very minor feature indeed, both because it arises in an uncommon situation (using windows headers), it could be fixed by the compiler/linker.

BTW, I was the one who requested the feature in the first place. It was important for template metaprogramming. When you do something complicated, the obj files contain masses of compile-time constants. (I was experiencing 5Mb obj files where only a single int was used at runtime!) It takes ages to save such a large obj file. Since you cannot take the address of such constants, there's no reason for them to be retained, and I requested that they be discarded from the obj file. Subsequently, Walter said that the fact that you can't take their address is a compiler bug, not an intentional feature. So we needed some additional language support in D2.0 to duplicate the functionality of the bug in D1.0 (!) Now that we have CTFE, it's a _lot_ less critical for metaprogramming. A local variable in a CTFE function is obviously not saved in the obj file.
Apr 29 2008
parent Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
Don wrote:
 Bruno Medeiros wrote:
 Around how many bytes are we talking about here, just to get a 
 concrete idea, does anyone know? I'm not familiar with the windows 
 headers nor their D bindings, although I recently checked some of the 
 windows d headers and there were many manifest constants. But I still 
 don't know if their size would amount to something that significant. 
 If for example, you have a cmd line program that prints one page of 
 it's syntax/usage, just that single string would occupy the same space 
 as 400 manifest constants or more.

void main() {} --> 79kB exe. ------- import win32.core; void main() {} --> 108kB exe. So it looks like it's less than 32K. Less than 40% of the size of the phobos runtime and gc. And a good linker would remove it ALL.

It is more than I expected, but I still don't find such size significant enough.
 
 BTW, I was the one who requested the feature in the first place.
 It was important for template metaprogramming. When you do something 
 complicated, the obj files contain masses of compile-time constants. (I 
 was experiencing 5Mb obj files where only a single int was used at 
 runtime!) It takes ages to save such a large obj file.
 Since you cannot take the address of such constants, there's no reason 
 for them to be retained, and I requested that they be discarded from the 
 obj file.
 

5Mb!? Well, that's certainly significant enough then. Still the feature is only valid because the compiler/linker doesn't discard them. Hopefully in the future that will change, and the compiler won't generate unnecessary symbols in the first place. -- Bruno Medeiros - Software Developer, MSc. in CS/E graduate http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Apr 29 2008
prev sibling parent terranium <spam here.lot> writes:
 manifest 
 constants do not take up space.

//alias invariant manifest; alias enum manifest; manifest int id=123;
Apr 28 2008