Jump to page: 1 24  
Page
Thread overview
no macros in D?
May 04, 2005
Maxime Larose
May 04, 2005
Andrew Fedoniouk
May 04, 2005
Vathix
May 04, 2005
Andrew Fedoniouk
May 04, 2005
Maxime Larose
May 04, 2005
Andrew Fedoniouk
May 05, 2005
Chris Sauls
May 04, 2005
Uwe Salomon
May 04, 2005
Uwe Salomon
May 04, 2005
Ben Hinkle
May 04, 2005
Sean Kelly
May 04, 2005
Maxime Larose
May 04, 2005
Sean Kelly
May 04, 2005
Russ Lewis
May 04, 2005
Maxime Larose
May 04, 2005
Russ Lewis
May 04, 2005
Sean Kelly
May 04, 2005
Maxime Larose
May 04, 2005
Kramer
May 04, 2005
Walter
May 05, 2005
Maxime Larose
May 05, 2005
Chris Sauls
May 05, 2005
Maxime Larose
May 05, 2005
Vladimir
May 05, 2005
Vladimir
May 05, 2005
Benji Smith
May 05, 2005
Ben Hinkle
May 05, 2005
Benji Smith
May 05, 2005
Ben Hinkle
May 05, 2005
Benji Smith
May 05, 2005
Russ Lewis
Heap vs stack allocation
May 05, 2005
Maxime Larose
May 05, 2005
Sean Kelly
May 05, 2005
Maxime Larose
May 05, 2005
Benji Smith
May 05, 2005
Russ Lewis
May 05, 2005
Ben Hinkle
May 05, 2005
Russ Lewis
May 05, 2005
Sean Kelly
May 05, 2005
Russ Lewis
May 04, 2005
I'm I missing something or is there no way to have true macros in D?  The facilities to generate boiler plate code doesn't seem to go far enough.

For instance, I want to define an alias/template/mixin/whatever for simplifying the syntax to create stuff on the stack. Here is how the code would look ideally:

void main()
{
  char[] abc = stack_char(1000);
}

stack_char being a specialization of a stack_array!(T) or something like
that.

I tried a thousand variations with mixins, templates and aliases, the compiler is always complaining one way or the other. And when it works, a function is called (defeating the purpose of creating the variable in the local stack).

Even doing something very simply like:
alias cast(char*)std.c.stdlib.alloca stack_char;

doesn't work. The compiler complains about the (char*).


Less ideally, I thought of doing:
stack_array(abc, char, 1000);

which would expand to:
char[] abc = (cast(char*)std.c.stdlib.alloca(1000))[0..1000]

This seems simple enough. However, it doesn't work because "abc" is not defined prior to use. (Even when I use an "alias" parameter for the template.)

I'm I missing something? This seems like very simple stuff...





May 04, 2005
Maxime,

could you check your code again?
Following just works:
----------------------------------
import std.stdio;
import std.c.stdlib;

template stackArray(T, uint N)
{
  char[] v = (cast(T*)std.c.stdlib.alloca(N))[0..N];
}

int main(char[][] args)
{
  mixin stackArray!(char,1000);
  v[0] = 'h';
  writef("%d\n", v.length );
  return 0;
}
-----------------------------------


"Maxime Larose" <mlarose@broadsoft.com> wrote in message news:d5apgr$279m$1@digitaldaemon.com...
> I'm I missing something or is there no way to have true macros in D?  The facilities to generate boiler plate code doesn't seem to go far enough.
>
> For instance, I want to define an alias/template/mixin/whatever for simplifying the syntax to create stuff on the stack. Here is how the code would look ideally:
>
> void main()
> {
>  char[] abc = stack_char(1000);
> }
>
> stack_char being a specialization of a stack_array!(T) or something like
> that.
>
> I tried a thousand variations with mixins, templates and aliases, the compiler is always complaining one way or the other. And when it works, a function is called (defeating the purpose of creating the variable in the local stack).
>
> Even doing something very simply like:
> alias cast(char*)std.c.stdlib.alloca stack_char;
>
> doesn't work. The compiler complains about the (char*).
>
>
> Less ideally, I thought of doing:
> stack_array(abc, char, 1000);
>
> which would expand to:
> char[] abc = (cast(char*)std.c.stdlib.alloca(1000))[0..1000]
>
> This seems simple enough. However, it doesn't work because "abc" is not defined prior to use. (Even when I use an "alias" parameter for the template.)
>
> I'm I missing something? This seems like very simple stuff...
>
>
>
>
> 


May 04, 2005
On Wed, 04 May 2005 11:41:23 -0400, Andrew Fedoniouk <news@terrainformatica.com> wrote:

> Maxime,
>
> could you check your code again?
> Following just works:
> ----------------------------------
> import std.stdio;
> import std.c.stdlib;
>
> template stackArray(T, uint N)
> {
>   char[] v = (cast(T*)std.c.stdlib.alloca(N))[0..N];
> }
>
> int main(char[][] args)
> {
>   mixin stackArray!(char,1000);
>   v[0] = 'h';
>   writef("%d\n", v.length );
>   return 0;
> }
> -----------------------------------


Beat me to it :p


private import std.c.stdlib, std.stdio;

template stack_array(T, size_t count)
{
   T[] value = (cast(T*)std.c.stdlib.alloca(count * T.sizeof))[0 .. count];
}

int main()
{
   mixin stack_array!(char, 500) abc;

   abc.value[0 .. 500] = 'f';
   writefln("The length is %d", abc.value.length);
   writefln("The answer is '%s'", abc.value);

   return 0;
}
May 04, 2005
It is not that simple, because alloca() allocates on the stack of the called function, thus you cannot insert it into a sub-function (if it returns, the allocated space is gone). You have to write a little more sophisticated template like QVarLengthArray from Qt 4.0 (should be at http://doc.trolltech.com/4.0/qvarlengtharray.html). When i have finished indigo.string (a QString lookalike), i will perhaps work on that. Just to give you a hint:


struct VarLengthArray(T, size_t stackSize)
{
private:
  T[stackSize] m_stackData;

public:
  T[] data(size_t neededSize)
  {
    if (neededSize <= stackSize)
      return m_stackData[0 .. neededSize];
    else
      return new T[neededSize];
  }	
}


Well, this is really a simple algorithm, but it shows the principle quite well. You allocate a fixed size on the stack, and if that's not enough, you take from the heap. You can use that like this:


void myFunc(int someParam, size_t elemCountToWorkWith)
{
  VarLengthArray!(uint, 256) stackArray;
  uint[] vec = stackArray.data(elemCountToWorkWith);

  // Do something with vec...
  foreach (uint x; vec)
    // ...
}


Here you have a function that has to do something with a certain number of uint's, which will be less than 256 in 90% of the cases (or whatever percentage you need). If elemCountToWorkWith is under 256, this array will be allocated on the stack (very fast), otherwise on the heap. If you call this function often, this will make a significant speed improvement (and of course create less garbage). But i do not know how much faster/slower than alloca() this variant is (at least it does not safe you some typing. :)

Ciao
uwe
May 04, 2005
> template stackArray(T, uint N)
> {
>   char[] v = (cast(T*)std.c.stdlib.alloca(N))[0..N];
> }

Uh. Isn't that better? :

template stackArray(T, size_t N)
{
  T[] vec = (cast(T*) std.c.stdlib.alloca(N * T.sizeof))[0 .. N];
}

And some specialization for N*T.sizeof > xxx bytes would do some good, to...

Ciao
uwe
May 04, 2005
"Maxime Larose" <mlarose@broadsoft.com> wrote in message news:d5apgr$279m$1@digitaldaemon.com...
> I'm I missing something or is there no way to have true macros in D?  The facilities to generate boiler plate code doesn't seem to go far enough.
[snip]
> char[] abc = (cast(char*)std.c.stdlib.alloca(1000))[0..1000]

It would be nice if placement worked for char[]s:
char[] abc = new(alloca(1000))char[1000];
From my experiments the line above compiles but it looks like it winds up
allocating from the GC. Note in the example about alloca it would be nice if
the "std.c.stdlib" were removed since it makes the code look nastier than it
has to be. I suppose it tells the reader that alloca is in std.c.stdlib but
it gives the impression it should always be used when allocating from the
stack.


May 04, 2005
Oh, yeh :)))

Thanks a lot.
As always with concept cars
they can move in theory but in practice only on podium.
That was just such a car. Quick and ugly.

Beg my pardon,

Uwe, thanks you too.

Andrew.




"Vathix" <vathix@dprogramming.com> wrote in message news:op.sp9cntpqkcck4r@esi...
> On Wed, 04 May 2005 11:41:23 -0400, Andrew Fedoniouk <news@terrainformatica.com> wrote:
>
>> Maxime,
>>
>> could you check your code again?
>> Following just works:
>> ----------------------------------
>> import std.stdio;
>> import std.c.stdlib;
>>
>> template stackArray(T, uint N)
>> {
>>   char[] v = (cast(T*)std.c.stdlib.alloca(N))[0..N];
>> }
>>
>> int main(char[][] args)
>> {
>>   mixin stackArray!(char,1000);
>>   v[0] = 'h';
>>   writef("%d\n", v.length );
>>   return 0;
>> }
>> -----------------------------------
>
>
> Beat me to it :p
>
>
> private import std.c.stdlib, std.stdio;
>
> template stack_array(T, size_t count)
> {
>    T[] value = (cast(T*)std.c.stdlib.alloca(count * T.sizeof))[0 ..
> count];
> }
>
> int main()
> {
>    mixin stack_array!(char, 500) abc;
>
>    abc.value[0 .. 500] = 'f';
>    writefln("The length is %d", abc.value.length);
>    writefln("The answer is '%s'", abc.value);
>
>    return 0;
> }


May 04, 2005
In article <d5apgr$279m$1@digitaldaemon.com>, Maxime Larose says...
>
>I'm I missing something or is there no way to have true macros in D?  The facilities to generate boiler plate code doesn't seem to go far enough.

Mixins are about as close as you can get.  Why not use plain old functions and compile with -inline?  That should address performance concerns in most cases.


Sean


May 04, 2005
> >> template stackArray(T, uint N)
> >> {
> >>   char[] v = (cast(T*)std.c.stdlib.alloca(N))[0..N];
> >> }

This variant is not really re-useable because the variable name is fixed, i.e. "v". It prevents you from having many such variables in the same function (or forces you to define many different templates...)  (I had tried it)


> > template stack_array(T, size_t count)
> > {
> >    T[] value = (cast(T*)std.c.stdlib.alloca(count * T.sizeof))[0 ..
> > count];
> > }
> >
> > int main()
> > {
> >    mixin stack_array!(char, 500) abc;
> >
> >    abc.value[0 .. 500] = 'f';

This variant is good and generally useable. I didn't try it, because I didn't know it was possible to put the name of a variable after the mixin... It's not in the doc at any rate and not really intuitive (IMO). But if it works... ;)

All right, thanks. I'll try it out tonight.

Max





"Andrew Fedoniouk" <news@terrainformatica.com> wrote in message news:d5ariq$29j2$1@digitaldaemon.com...
> Oh, yeh :)))
>
> Thanks a lot.
> As always with concept cars
> they can move in theory but in practice only on podium.
> That was just such a car. Quick and ugly.
>
> Beg my pardon,
>
> Uwe, thanks you too.
>
> Andrew.
>
>
>
>
> "Vathix" <vathix@dprogramming.com> wrote in message news:op.sp9cntpqkcck4r@esi...
> > On Wed, 04 May 2005 11:41:23 -0400, Andrew Fedoniouk <news@terrainformatica.com> wrote:
> >
> >> Maxime,
> >>
> >> could you check your code again?
> >> Following just works:
> >> ----------------------------------
> >> import std.stdio;
> >> import std.c.stdlib;
> >>
> >> template stackArray(T, uint N)
> >> {
> >>   char[] v = (cast(T*)std.c.stdlib.alloca(N))[0..N];
> >> }
> >>
> >> int main(char[][] args)
> >> {
> >>   mixin stackArray!(char,1000);
> >>   v[0] = 'h';
> >>   writef("%d\n", v.length );
> >>   return 0;
> >> }
> >> -----------------------------------
> >
> >
> > Beat me to it :p
> >
> >
> > private import std.c.stdlib, std.stdio;
> >
> > template stack_array(T, size_t count)
> > {
> >    T[] value = (cast(T*)std.c.stdlib.alloca(count * T.sizeof))[0 ..
> > count];
> > }
> >
> > int main()
> > {
> >    mixin stack_array!(char, 500) abc;
> >
> >    abc.value[0 .. 500] = 'f';
> >    writefln("The length is %d", abc.value.length);
> >    writefln("The answer is '%s'", abc.value);
> >
> >    return 0;
> > }
>
>


May 04, 2005
In debug mode, that would simply crash... I.e. the "stack" allocated variable would be allocated on the stack of the callee, not the caller. Inlining only partially solves the problem in that you are never sure of what gets inlined and what does not. It leads to non-portable code at its worst.



"Sean Kelly" <sean@f4.ca> wrote in message news:d5asqh$2arf$1@digitaldaemon.com...
> In article <d5apgr$279m$1@digitaldaemon.com>, Maxime Larose says...
> >
> >I'm I missing something or is there no way to have true macros in D?  The facilities to generate boiler plate code doesn't seem to go far enough.
>
> Mixins are about as close as you can get.  Why not use plain old functions
and
> compile with -inline?  That should address performance concerns in most
cases.
>
>
> Sean
>
>


« First   ‹ Prev
1 2 3 4