Thread overview
Const and enum optimizations
Jan 03, 2013
Phil Lavoie
Jan 03, 2013
Jonathan M Davis
Jan 03, 2013
Phil Lavoie
Jan 03, 2013
Ali Çehreli
Jan 03, 2013
Jonathan M Davis
January 03, 2013
Hi,

I have a question concerning compiler optimizations and their likelihood for const vs. enum declarations.

I came across some code recently that had a bunch of const declarations that were extracted from a C header. In this very header, those definitions are in fact #define clauses.

I was under the impression that those should be translated as:
header.c:
#define MY_CONST 1
...
module.d:
enum {
  MY_CONST = 1
}
and not:
module.d:
const MY_CONST = 1;

I thought that MY_CONST enum is more likely optimized since its address cannot be taken? But my real question is this: is a declaration like MY_CONST (enum) always optimized space wise (for dmd)? What is the likelihood of MY_CONST (const) being optimized as well?

Thanks!
Phil
January 03, 2013
On Thursday, January 03, 2013 16:58:11 Phil Lavoie wrote:
> Hi,
> 
> I have a question concerning compiler optimizations and their likelihood for const vs. enum declarations.
> 
> I came across some code recently that had a bunch of const declarations that were extracted from a C header. In this very header, those definitions are in fact #define clauses.
> 
> I was under the impression that those should be translated as:
> header.c:
> #define MY_CONST 1
> ...
> module.d:
> enum {
> MY_CONST = 1
> }
> and not:
> module.d:
> const MY_CONST = 1;
> 
> I thought that MY_CONST enum is more likely optimized since its
> address cannot be taken? But my real question is this: is a
> declaration like MY_CONST (enum) always optimized space wise (for
> dmd)? What is the likelihood of MY_CONST (const) being optimized
> as well?

All enums are effectively copy-pasted when they're used. That's why having enums of array literals can be a bad idea.

enum a = [1, 2, 3, 4];
foo(a);
bar(a);

becomes

foo([1, 2, 3, 4]);
bar([1, 2, 3, 4]);

so you get double the allocations. If you do

const a = [1, 2, 3, 4];

then you've declared an actual variable whose address can be taken, and the allocation will occur only once.

const variables outside of local scope _won't_ be optimized out of existence, but at local scope, they may be optimized out by constant folding. The enum version at local scope is just as likely to be optimized as if you copy-pasted the value yourself rather than using an enum. But what exactly dmd ultimately optimizes probably depends on the code, and you'd have to look at the generated assembly to know for sure.

But if your concern is const variables at module scope being optimized out of existence, it is my understanding that they won't be.

- Jonathan M Davis
January 03, 2013
> But if your concern is const variables at module scope being optimized out of
> existence, it is my understanding that they won't be.

All right, thanks for your answer! My concern is indeed const variable at module scope. I felt like using enums for #define translations were more appropriate, and you answer seems to confirm that.

Also, thank you for elaborating on the case where the array is created twice.

Phil
January 03, 2013
On 01/03/2013 07:58 AM, Phil Lavoie wrote:

> header.c:
> #define MY_CONST 1
> ...
> module.d:
> enum {
> MY_CONST = 1
> }

Further, there is no need for that anonymous scope in D:

    enum MY_CONST = 1;

Even further, I am one of those who reserve all capitals to macros. Since there are no macros in D, this is my choice:

    enum myConst = 1;

I know that there are others who use all capitals for manifest constants but I fail to see the benefit of doing that. Nobody wants to or able to modify constants anyway. :)

Ali

January 03, 2013
On Thursday, January 03, 2013 13:34:16 Ali Çehreli wrote:
> On 01/03/2013 07:58 AM, Phil Lavoie wrote:
> > header.c:
> > #define MY_CONST 1
> > ...
> > module.d:
> > enum {
> > MY_CONST = 1
> > }
> 
> Further, there is no need for that anonymous scope in D:
> 
> enum MY_CONST = 1;
> 
> Even further, I am one of those who reserve all capitals to macros. Since there are no macros in D, this is my choice:
> 
> enum myConst = 1;
> 
> I know that there are others who use all capitals for manifest constants but I fail to see the benefit of doing that. Nobody wants to or able to modify constants anyway. :)

Phobos's style guidelines prohibit all caps. Manifest constants are camelCased just like variables and functions are. So, the standard library doesn't have anything which is all caps unless it's old code and doesn't follow Phobos' current style guidelines.

Personally, I think that all caps is hideous. It makes sense in C/C++ for macros due to how the preprocessor works, but it's completely unnecessary in D. I'm sure that some people still use all caps though.

- Jonathan M Davis