Alternative to C++ macro in D

Ali Çehreli acehreli at yahoo.com
Mon Nov 4 00:20:37 UTC 2019


On 11/03/2019 08:55 AM, Vinod K Chandran wrote:
 > Hi all,
 > I can do this in C++.
 > #include <iostream>
 > using namespace std ;
 >
 > #define end };
 > #define log(x)  cout << x << endl
 > #define wait std::cin.get()

There is nothing that stops one from using the C++ preprocessor on any 
text file. For example, you can do the following wherever GCC exists. If 
there are the following lines in a D file:

#define XYZ 42

auto a = XYZ;

Then you can pass it through the preprocessor like this:

   cpp foo.d

In fact, that's one of the tricks dpp uses to make C++ headers usable in 
D code:

   https://github.com/atilaneves/dpp

As you can see above, compile-time constants are defined with 'enum' in D:

enum XYZ = 42;

auto a = XYZ;

Beware though: Do not do that with arrays though, as every usage of an 
'enum' array causes dynamic memory allocation at run time.

enum myConstants = [ 1, 2 ];

bool foo(int i) {
   import std.algorithm : canFind;
   return myConstants.canFind(i);    // <-- DON'T DO THIS
}

In addition to the enum version of an array (which you may need to use 
e.g. with 'static foreach') , also use a run-time initialized array:

// Use this e.g. for 'static foreach'
enum myConstants_enum = [ 1, 2 ];

// Use this for run-time code
immutable int[] myConstants;
shared static this() {
   // This is the initialization of the immutable array:
   myConstants = myConstants_enum;
}

bool foo(int i) {
   import std.algorithm : canFind;
   return myConstants.canFind(i);    // <-- DO THIS
}

Even though I've known about this gotcha, this wisdom comes from 
profiling my program by compiling with dmd's '-profile=gc' option. It 
was pretty obvious in the generated 'profilegc.log' file that I was 
causing such unnecessary memory allocations.

Ali



More information about the Digitalmars-d-learn mailing list