www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - porting GCC macro to D

reply "ketmar" <ketmar ketmar.no-ip.org> writes:
i have some C code like this:

void func0 (void) { … }
int func1 (void) { … return smth+42; }

#define MYMACRO()  ({ func0(); func1(); })

int v;
…
v = MYMACRO()-16;


what it does? it uses GCC extension "statement expression" which 
allows to place almost arbitrary C operator block inside any 
expression. result of evaluating this "operator block" will be 
value of the last operator in it (return value of func1() in my 
case). this block can contain ifs, switches, local vars, local 
function declarations and so on.

in D we have no "statement expressions" in this form, afaik, and 
comma operator is very limited (and will be deprecated anyway). 
how can i reproduce such thing in D? i.e. i want to write 
something like:

v = mixin(MYMACRO())-16;

and have the same effect as in C code: all MYMACRO content (this 
can be almost anything) *always* inlined. the only thing i was 
able to think out is to generate nested functions with immediate 
call in MYMACRO, but it will not guarantee inlining (i.e. i must 
trust compiler intellgence here).
Apr 04 2014
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
ketmar:

 and have the same effect as in C code: all MYMACRO content 
 (this can be almost anything) *always* inlined.
Define a function. And in D there is no way to require a sure inline. Some people have asked for a __forceinline but Andrei&Walter don't seem sufficiently interested. Bye, bearophile
Apr 04 2014
prev sibling parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Friday, 4 April 2014 at 13:22:39 UTC, ketmar wrote:
 i have some C code like this:

 void func0 (void) { … }
 int func1 (void) { … return smth+42; }

 #define MYMACRO()  ({ func0(); func1(); })

 int v;
 …
 v = MYMACRO()-16;

 <snip>

 v = mixin(MYMACRO())-16;

 and have the same effect as in C code: all MYMACRO content 
 (this can be almost anything) *always* inlined. the only thing 
 i was able to think out is to generate nested functions with 
 immediate call in MYMACRO, but it will not guarantee inlining 
 (i.e. i must trust compiler intellgence here).
You can hack around that limitation if it's acceptable to use a temporary variable: enum MYMACRO(alias output) = `func0(); ` ~ output.stringof ~ ` = func1();`; ... int a; mixin(MYMACRO!a); v = a - 16; This uses the new enum template syntax available in current DMD, alternatively use: template MYMACRO(alias output) { enum MYMACRO = ...; } Unfortunately, you cannot use template mixins for this, because they can only contain declarations, not statements.
Apr 04 2014
parent reply "ketmar" <ketmar ketmar.no-ip.org> writes:
 You can hack around that limitation if it's acceptable to use a 
 temporary variable:
sure, and i can rewrite the whole call, passing destination variable as template argument. but this looks ugly. thanx for the answer anyway (and bearophile too).
 Unfortunately, you cannot use template mixins for this, because 
 they can only contain declarations, not statements.
yes, i found that hard way — with experiments. it's a pity, i think.
Apr 04 2014
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 04/04/2014 08:42 AM, ketmar wrote:

 You can hack around that limitation if it's acceptable to use a
 temporary variable:
sure, and i can rewrite the whole call, passing destination variable as template argument. but this looks ugly.
A regular function would work too: void func0 () { } int func1 () { return 42; } int MYMACRO() { func0(); return func1(); } void main() { int v = MYMACRO() - 16; } Ali
Apr 04 2014
parent "ketmar" <ketmar ketmar.no-ip.org> writes:
 A regular function would work too:
alas, no inline guarantee. and speed is critical there.
Apr 05 2014