translate a macro to D

Steven Schveighoffer schveiguy at yahoo.com
Thu Jul 7 08:57:51 PDT 2011


On Thu, 07 Jul 2011 11:38:05 -0400, teo <teo.ubuntu at yahoo.com> wrote:

> On Wed, 06 Jul 2011 16:21:31 +0200, Trass3r wrote:
>
>> Am 06.07.2011, 16:15 Uhr, schrieb teo <teo.ubuntu at yahoo.com>:
>>
>>> 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.

>
> Example:
> printf("%ld\n", TYPESIZE(short));
> printf("%ld\n", TYPESIZE(struct A));

printf("%ld %ld\n", short.sizeof, A.sizeof);

>
> The  TYPESIZE macro is used within another macro which defines constants.
> #define M(a,b,size) \
> 	 ((a) << SHIFT_A) | \
> 	 ((b)   << SHIFT_B) | \
> 	 ((size) << SHIFT_SIZE))
> #define MM(a,b,type)	    M((a),(b),(TYPESIZE(type)))

Define MM and M as normal functions as Trass3r suggested, then use  
type.sizeof.

> Example:
> #define C1    MM(1, 2, struct A)
> #define C2    MM(3, 4, struct B)

Note, in D, to ensure compile-time evaluation, it's useful to have a  
template that does this:

template MM(uint a, uint b, T)
{
   enum MM = (a << SHIFT_A) | (b << SHIFT_B) | (T.sizeof << SHIFT_SIZE);
}

Usage is like:

enum C1 = MM!(1, 2, A);
enum C2 = MM!(3, 4, B);


More information about the Digitalmars-d-learn mailing list