www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - compile time output

reply Trass3r <mrmocool gmx.de> writes:
Is there any way to output information at compile time other than 
pragma(msg?
pragma is driving me crazy, the following doesn't work:

auto members = __traits(allMembers, typeof(this));
foreach(m; members)
{
	pragma(msg, m);
}

-> Error: string expected for message, not 'm'

Though the docs clearly state:
allMembers: "An array of string literals is returned"
Also checked that, m is of type invariant(char)[].


Any ideas? -.-
Jan 20 2009
next sibling parent reply Bill Baxter <wbaxter gmail.com> writes:
On Wed, Jan 21, 2009 at 12:36 AM, Trass3r <mrmocool gmx.de> wrote:
 Is there any way to output information at compile time other than
 pragma(msg?
 pragma is driving me crazy, the following doesn't work:

 auto members = __traits(allMembers, typeof(this));
 foreach(m; members)
 {
        pragma(msg, m);
 }

 -> Error: string expected for message, not 'm'

 Though the docs clearly state:
 allMembers: "An array of string literals is returned"
 Also checked that, m is of type invariant(char)[].


 Any ideas? -.-
try indexing explicitly or using ref: foreach(i,m; members) { pragma(msg, members[i]); } foreach(ref m; members) { pragma(msg, m); } Latter one may not be useful. I can't recall. --bb
Jan 20 2009
parent Trass3r <mrmocool gmx.de> writes:
Bill Baxter schrieb:
 try indexing explicitly or using ref:
 
 foreach(i,m; members)
 {
     pragma(msg, members[i]);
 }
 
 foreach(ref m; members)
 {
     pragma(msg, m);
 }
 
 Latter one may not be useful.  I can't recall.
Neither one works for me :(
Jan 20 2009
prev sibling next sibling parent Ary Borenszweig <ary esperanto.org.ar> writes:
Trass3r wrote:
 Is there any way to output information at compile time other than 
 pragma(msg?
 pragma is driving me crazy, the following doesn't work:
 
 auto members = __traits(allMembers, typeof(this));
Kind of offtopic, but I tried this (with typeof(Foo) and Foo is defined in the same module) in Descent and I get a NullPointerException. :-( I thought the port to Java was wrong so I compared to dmd's code. In traits.c I can see: --- else if (ident == Id::allMembers || ident == Id::derivedMembers) { if (dim != 1) goto Ldimerror; Object *o = (Object *)args->data[0]; Dsymbol *s = getDsymbol(o); --- and in template.c getDsymbol says: --- Dsymbol *getDsymbol(Object *oarg) { Dsymbol *sa; Expression *ea = isExpression(oarg); if (ea) { // (snip) } else { // Try to convert Type to symbol Type *ta = isType(oarg); if (ta) sa = ta->toDsymbol(NULL); else sa = isDsymbol(oarg); // if already a symbol } return sa; } --- and of course oarg is a type, it's a TypeTypeof, so TypeTypeof::toDsymbol is invoked. Note that in this point sc is NULL. --- Dsymbol *TypeTypeof::toDsymbol(Scope *sc) { Type *t; t = semantic(0, sc); if (t == this) return NULL; return t->toDsymbol(sc); } --- and finally... --- Type *TypeTypeof::semantic(Loc loc, Scope *sc) { Expression *e; Type *t; sc->intypeof++; // sc is NULL!! exp = exp->semantic(sc); sc->intypeof--; // (snip) } --- and that's why I get a NPE. But compiling with dmd works fine. Unfortunately I don't have with me the necessary stuff to debug dmd... does anyone know what's going on? Thanks, Ary
Jan 20 2009
prev sibling next sibling parent reply BCS <ao pathlink.com> writes:
Reply to Trass3r,

 Is there any way to output information at compile time other than
 pragma(msg?
 pragma is driving me crazy, the following doesn't work:
 auto members = __traits(allMembers, typeof(this));
 foreach(m; members)
 {
 pragma(msg, m);
 }
 -> Error: string expected for message, not 'm'
 
 Though the docs clearly state:
 allMembers: "An array of string literals is returned"
 Also checked that, m is of type invariant(char)[].
 Any ideas? -.-
 
I don't do 2.0 but it looks to me like your mixing runtime and compile time stuff. A foreach over an array is a runtime foreach.
Jan 20 2009
parent reply Trass3r <mrmocool gmx.de> writes:
BCS schrieb:
 I don't do 2.0 but it looks to me like your mixing runtime and compile 
 time stuff. A foreach over an array is a runtime foreach.
 
Do you know how I could make it run at compile-time?
Jan 20 2009
parent reply BCS <ao pathlink.com> writes:
Reply to Trass3r,

 BCS schrieb:
 
 I don't do 2.0 but it looks to me like your mixing runtime and
 compile time stuff. A foreach over an array is a runtime foreach.
 
Do you know how I could make it run at compile-time?
template Tpl(T...) { alias T Tpl; } template Range(int l, int u) { static if(l<u) alias Tpl!(l, Range!(l+1,u)) Range; else alias Tpl!(l) Range; } const char[][] set = ["Hello"[], "world" ]; void main() { foreach(str; Range!(0,set.length-1)) // compile time foreach over the numbers from 0 to set.length-1 pragma(msg, set[str]); }
Jan 20 2009
parent reply Trass3r <mrmocool gmx.de> writes:
BCS schrieb:
 template Tpl(T...)
 {
  alias T Tpl;
 }
 
 template Range(int l, int u)
 {
  static if(l<u)
    alias Tpl!(l, Range!(l+1,u)) Range;
  else
    alias Tpl!(l) Range;
 }
 
 const char[][] set = ["Hello"[], "world" ];
 
 void main()
 {
  foreach(str; Range!(0,set.length-1)) // compile time foreach over the 
 numbers from 0 to set.length-1
    pragma(msg, set[str]);
 }
 
Still doesn't work for this code (used with a mixin): template classMixin() { static this() { auto members = __traits(allMembers, typeof(this)); foreach(m; Range!(0, members.length-1)) { pragma(msg, members[m]); static if (is (typeof(__traits(getMember, this, members[m])) F == function)) { pragma(msg, "function"); } } } } -> Error: string expected for message, not 'members[0u]' Leaving out the first pragma, compiles but doesn't output anything. Replacing members[m] with a valid method name, such as "__ctor" it outputs function correctly :(
Jan 20 2009
parent reply BCS <ao pathlink.com> writes:
Reply to Trass3r,

 auto members = __traits(allMembers, typeof(this));
try switching that to
 const[][] members = __traits(allMembers, typeof(this));
if that doesn't fix it try dropping this part (it might make it clearer what's going on)
 static if (is (typeof(__traits(getMember, this, members[m])) F ==
 function))
 {
 pragma(msg, "function");
 }
Looking at the rest of the thread, I think you might be looking at a bug.
Jan 20 2009
parent reply Trass3r <mrmocool gmx.de> writes:
This works:

template classMixin()
{
static this()
{
	const string[] members = __traits(allMembers, typeof(this));
	pragma(msg, foo(members));
}
}

string foo(const string[] members)
{
	string result;
	foreach(m; members)
		result ~= m ~ " ";
	return result;
}


But there must exist a better solution to this.
Jan 20 2009
parent reply Trass3r <mrmocool gmx.de> writes:
Trass3r schrieb:
 This works:
 
 string foo(const string[] members)
 {
     string result;
     foreach(m; members)
         result ~= m ~ " ";
     return result;
 }
 
Furthermore there seems to be no way to use these member names in a __traits(getMember, class, m) call. This is driving me crazy.
Jan 20 2009
parent Bill Baxter <wbaxter gmail.com> writes:
On Wed, Jan 21, 2009 at 8:25 AM, Trass3r <mrmocool gmx.de> wrote:
 Trass3r schrieb:
 This works:

 string foo(const string[] members)
 {
    string result;
    foreach(m; members)
        result ~= m ~ " ";
    return result;
 }
Furthermore there seems to be no way to use these member names in a __traits(getMember, class, m) call. This is driving me crazy.
Well, it does start with two underscores. That may be trying to tell you something. :-) If you find a real bug definitely report it. Also note that your bug reports will be treated much more seriously if you can provide a compelling use case which is difficult or impossible to work around short of fixing the bug. "If you fix this then I will be able create cool thing X" seems to increase your chances of getting a fix significantly. --bb
Jan 20 2009
prev sibling parent reply Sergey Gromov <snake.scaly gmail.com> writes:
Tue, 20 Jan 2009 16:36:09 +0100, Trass3r wrote:

 Is there any way to output information at compile time other than 
 pragma(msg?
 pragma is driving me crazy, the following doesn't work:
 
 auto members = __traits(allMembers, typeof(this));
 foreach(m; members)
 {
 	pragma(msg, m);
 }
 
 -> Error: string expected for message, not 'm'
 
 Though the docs clearly state:
 allMembers: "An array of string literals is returned"
 Also checked that, m is of type invariant(char)[].
 
 Any ideas? -.-
Weird. The following code does not compile: class Cls { int bar; char[] baz; } string foo() { auto members = __traits(allMembers, Cls); return ""; } pragma(msg, foo());
dmd -c test.d
test.d(11): Error: cannot evaluate foo() at compile time test.d(11): pragma msg string expected for message, not 'foo()' Comment out the traits and it compiles. Traits are supposed to be compile-time. How's that possible for them to prevent compile-time evaluation?
Jan 20 2009
next sibling parent reply Trass3r <mrmocool gmx.de> writes:
Sergey Gromov schrieb:
  > class Cls
 {
   int bar;
   char[] baz;
 }
 string foo()
 {
   auto members = __traits(allMembers, Cls);
   return "";
 }
 pragma(msg, foo());
 
 dmd -c test.d
test.d(11): Error: cannot evaluate foo() at compile time test.d(11): pragma msg string expected for message, not 'foo()' Comment out the traits and it compiles. Traits are supposed to be compile-time. How's that possible for them to prevent compile-time evaluation?
Seeing this really simple example crashing makes me think that this has to be a bug.
Jan 20 2009
parent reply BCS <ao pathlink.com> writes:
Reply to Trass3r,

 Sergey Gromov schrieb:
 
 auto members = __traits(allMembers, Cls);
Seeing this really simple example crashing makes me think that this has to be a bug.
that auto might be mucking it up (if so it would be a bug).
Jan 20 2009
parent Sergey Gromov <snake.scaly gmail.com> writes:
Tue, 20 Jan 2009 21:12:18 +0000 (UTC), BCS wrote:

 Reply to Trass3r,
 
 Sergey Gromov schrieb:
 
 auto members = __traits(allMembers, Cls);
Seeing this really simple example crashing makes me think that this has to be a bug.
that auto might be mucking it up (if so it would be a bug).
Bingo. Replacing it with string[] members = __traits(allMembers, Cls); makes it compile. Therefore class Cls { int bar; char[] baz; } string foo() { string[] members = __traits(allMembers, Cls); string result; foreach(m; members) result ~= m ~ " "; return result; } pragma(msg, foo()); works.
Jan 20 2009
prev sibling parent Christopher Wright <dhasenan gmail.com> writes:
Sergey Gromov wrote:
 Comment out the traits and it compiles.  Traits are supposed to be
 compile-time.  How's that possible for them to prevent compile-time
 evaluation?
It's the amazing powers of the DMD CTFE engine! And it's why I don't use d2 these days. I think I'll dust off some old code I have that worked with dmd 2.009 (and failed with 2.010 and 2.011) and try making it work. I don't think the bugs that I filed in reference to that code ever got fixed, though.
Jan 20 2009