What is the best way to translate following to D?
#define MAKELONG(a, b) \
((LONG) (((WORD) (a)) | ((DWORD) ((WORD) (b))) << 16))
The point is I would like to be able to use that at compile-time. The
macro is supposed to define some constants.

What is the best way to translate following to D?
#define MAKELONG(a, b) \
((LONG) (((WORD) (a)) | ((DWORD) ((WORD) (b))) << 16))
The point is I would like to be able to use that at compile-time. The
macro is supposed to define some constants.

Just turn it into a function.
If you assign it to an enum or use it as an initializer for global
immutables it should be evaluated at compile-time.

What is the best way to translate following to D?
#define MAKELONG(a, b) \
((LONG) (((WORD) (a)) | ((DWORD) ((WORD) (b))) << 16))
The point is I would like to be able to use that at compile-time. The
macro is supposed to define some constants.

Just turn it into a function.
If you assign it to an enum or use it as an initializer for global
immutables it should be evaluated at compile-time.

What is the best way to translate following to D?
#define MAKELONG(a, b) \
((LONG) (((WORD) (a)) | ((DWORD) ((WORD) (b))) << 16))
The point is I would like to be able to use that at compile-time. The
macro is supposed to define some constants.

Just turn it into a function.
If you assign it to an enum or use it as an initializer for global
immutables it should be evaluated at compile-time.

Thank you. That did the trick.
However I am facing another problem:
There is a macro, which obtains the size of a type
#define TYPESIZE(t) (sizeof(t))

Well, I can't really say I understand the point of using this macro at
all. sizeof is a builtin, and part of the C spec. Why not just use
sizeof?
In d it's t.sizeof.

Hm... I once wrote a D module that accessed a linux device driver (ipmi
driver to be specific). I did it in D1, and I used CTFE. For sure,
t.sizeof should work instead of _IOC_TYPECHECK. But Linux supports a
multitude of CPUs, perhaps other CPUs need a different macro for this.
It's the only thing I can think of to explain having a specific macro to
do sizeof.
-Steve

driver to be specific). I did it in D1, and I used CTFE. For sure,
t.sizeof should work instead of _IOC_TYPECHECK. But Linux supports a
multitude of CPUs, perhaps other CPUs need a different macro for this.
It's the only thing I can think of to explain having a specific macro to
do sizeof.
-Steve

driver to be specific). I did it in D1, and I used CTFE. For sure,
t.sizeof should work instead of _IOC_TYPECHECK. But Linux supports a
multitude of CPUs, perhaps other CPUs need a different macro for this.
It's the only thing I can think of to explain having a specific macro to
do sizeof.
-Steve

Steve,
I translated those macros to regular functions and it works that way
(using T.sizeof), however I could have used a function template instead
as you suggested before and therefore I have a question:
Are there any benefits of using function templates instead of regular
functions in that particular case?
The above leads me to another question: are those functions evaluated at
compile-time? I suppose they are not.

I think you may be confusing function templates with plain templates? I
remember suggesting this:
template MM(uint a, uint b, T)
{
enum MM = (a << SHIFT_A) | (b << SHIFT_B) | (T.sizeof << SHIFT_SIZE);
}
which is *not* a function template, it's simply a template which evaluates
to an enum.
The advantage is, no matter where you use it, it is done at compile time.
For something like ioctl constants, this is important.
Let's take a simple example:
myconstant(uint x)
{
return x << 5;
}
Now, if you use it in some code:
ioctl(myconstant(2), ...);
In a standard build (i.e. without any switches), the call to myconstant is
made, and the shift is performed, even when the value is easily known at
compile time. Essentially you have wasted cycles computing the myconstant
result. If you have both optimization (-O) and inlining (-inline), this
might result in the correct constant being sent to ioctl, but there is a
better way...
If we simply wrap myconstant into a template enum:
template myconstantCT(uint x)
{
enum myconstantCT = myconstant(x);
}
myconstantCT is evaluated at compile time, and replace with the exact
number wherever you use it. This happens regardless of compiler switches:
ioctl(myconstantCT!2, ...)
This always results in simply passing a number to ioctl.
So the benefit of using a template enum to do parameterized constants is
that it guarantees compile time evaluation. This is a perfect fit for
IOCTL constants which never change.
-Steve