Jump to page: 1 2
Thread overview
toString() on struct template
Feb 28, 2007
Henning Hasemann
Feb 28, 2007
Reiner Pope
Feb 28, 2007
Henning Hasemann
Feb 28, 2007
mario pernici
Feb 28, 2007
Henning Hasemann
Mar 01, 2007
endea
Mar 01, 2007
Henning Hasemann
Mar 01, 2007
Daniel Keep
Mar 01, 2007
Henning Hasemann
Mar 01, 2007
Henning Hasemann
Mar 02, 2007
Daniel Keep
Mar 02, 2007
Henning Hasemann
Mar 02, 2007
Henning Hasemann
Mar 02, 2007
Henning Hasemann
Mar 02, 2007
Thomas Kuehne
Re: [SOLVED] toString() on struct template
Mar 02, 2007
Henning Hasemann
February 28, 2007
I have a struct template with just 2 data members
(thats why I'd actually preferred a struct over a class).

It implements several methods such as overloaded operators and the pseudo constructor roughly like this:

struct Vector2d(T) {
	T x, y;
	Vector2d!(T) opCall(T x, T y) {
	  Vector2d!(T) v;
	  v.x = x;
	  v.y = y;
	  return v;
	}
	char[] toString() {
	  return format("(%d|%d)", x, y);
	}
}

But the toString actually crashes hard everytime *before* the format-call. (Btw: Dont be afraid because of the %d's I actually only instantiate the template with int for testing).

Is there something wrong with my understanding or with the compiler
(tested dmd 1.005 and 1.007)?

Whats the proper way of implementing toString vor structs if not like this?

Henning
February 28, 2007
Henning Hasemann wrote:
> I have a struct template with just 2 data members
> (thats why I'd actually preferred a struct over a class).
> 
> It implements several methods such as overloaded operators
> and the pseudo constructor roughly like this:
> 
> struct Vector2d(T) {
> 	T x, y;
> 	Vector2d!(T) opCall(T x, T y) {
> 	  Vector2d!(T) v;
> 	  v.x = x;
> 	  v.y = y;
> 	  return v;
> 	}
> 	char[] toString() {
> 	  return format("(%d|%d)", x, y);
> 	}
> }

I couldn't get your code to work as is, because it wasn't a 'static' opCall. The following code, however, runs fine on my computer:

> import std.stdio;
> import std.string;
> 
> struct Vector2d(T) {
> 	T x, y;
> 	static Vector2d!(T) opCall(T x, T y) {
> 	  Vector2d!(T) v;
> 	  v.x = x;
> 	  v.y = y;
> 	  return v;
> 	}
> 	char[] toString() {
> 	  return format("(%d|%d)", x, y);
> 	}
> }
> 
> void main()
> {
>     auto a = Vector2d!(int)(5, 6);
>     writefln(a.toString());
> }

Hope that helps,

Reiner
February 28, 2007
Henning Hasemann Wrote:

> I have a struct template with just 2 data members
> (thats why I'd actually preferred a struct over a class).
> 
> It implements several methods such as overloaded operators and the pseudo constructor roughly like this:
> 
> struct Vector2d(T) {
> 	T x, y;
> 	Vector2d!(T) opCall(T x, T y) {
> 	  Vector2d!(T) v;
> 	  v.x = x;
> 	  v.y = y;
> 	  return v;
> 	}
> 	char[] toString() {
> 	  return format("(%d|%d)", x, y);
> 	}
> }
> 
> But the toString actually crashes hard everytime *before* the format-call. (Btw: Dont be afraid because of the %d's I actually only instantiate the template with int for testing).
> 
> Is there something wrong with my understanding or with the compiler
> (tested dmd 1.005 and 1.007)?
> 
> Whats the proper way of implementing toString vor structs if not like this?
> 
> Henning

It works in this example

void main()
 {
     Vector2d!(int) a;
     auto b = a(5,6);
     writefln(b);
 }

output: (5|6)

Mario


February 28, 2007
Hm, if I just break it down to that small example it works at expected, so my bug has to be somewhere else, sorry for bothering you before testing the minimal code myself.

Henning
February 28, 2007
On Thu, 01 Mar 2007 08:01:37 +1100
Reiner Pope <reIGNOREiner.poCAPSpe@gmFOOail.cBARom> wrote:

> I couldn't get your code to work as is, because it wasn't a 'static' opCall. The following code, however, runs fine on my computer:

sorry, I just forgot to copy the static. The opCall itself seems to work just fine.

Henning
March 01, 2007
Henning Hasemann kirjoitti:
> Hm, if I just break it down to that small example it works at expected,
> so my bug has to be somewhere else, sorry for bothering you before
> testing the minimal code myself.
> 
> Henning

"%d" formats int type, that might be problem for Vector2d!(other-than-int)
March 01, 2007
I think I got it now:
If you build the source together with the main function, there
is no problem.

However in my constellation (the struct an the code that calls toString in a linux static library which is linked against a main function) this error occurs. The stacktrace says something about TypeInfo IIRC.

So it seems this information gets lost somehow?
I use dmd-1.007 (tried with 1.005 too), build the library with rebuild-0.12.
Maybe I should say that I use derelict too, but the error also occurs when
toString is called before any derelict-function.

I will try to further reduce the example, maybe later today.

Henning
March 01, 2007

Henning Hasemann wrote:
> I think I got it now:
> If you build the source together with the main function, there
> is no problem.
> 
> However in my constellation (the struct an the code that calls toString in a linux static library which is linked against a main function) this error occurs. The stacktrace says something about TypeInfo IIRC.
> 
> So it seems this information gets lost somehow?
> I use dmd-1.007 (tried with 1.005 too), build the library with rebuild-0.12.
> Maybe I should say that I use derelict too, but the error also occurs when
> toString is called before any derelict-function.
> 
> I will try to further reduce the example, maybe later today.
> 
> Henning

You mentioned a library...  If I remember correctly (standard disclaimers apply), then templates are NOT compiled into a library.

For example, let's say you compiled the following file into a library:

struct Foo(T)
{
    void bar(T value)
    {
        writefln("%s", value);
    }
}

And then used it like so:

void main()
{
    Foo!(int) x;
    x.bar(42);
}

And finally compiled it like thus:

    dmd FooLib.lib main.d

This would fail since FooLib.lib doesn't actually *have* the implementation of Foo in it.  In order for D to compile a templated struct or class into a library, it would need to compile it for every possible type, which obviously isn't going to happen.

If you want to use templates in a library, you *need* to ship and compile against the source code, not against a precompiled library.  The one exception to this is that it should work for any templates you've explicitly instantiated. So, if you append this to Foo's source file:

  alias Foo!(int) FooInt;

then it should work.

	-- Daniel

-- 
Unlike Knuth, I have neither proven or tried the above; it may not even make sense.

v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/
March 01, 2007
On Thu, 01 Mar 2007 21:20:38 +1100
Daniel Keep <daniel.keep.lists@gmail.com> wrote:

> 
> 
> Henning Hasemann wrote:
> > I think I got it now:
> > If you build the source together with the main function, there
> > is no problem.
> > 
> > However in my constellation (the struct an the code that calls toString in a linux static library which is linked against a main function) this error occurs. The stacktrace says something about TypeInfo IIRC.
> > 
> > So it seems this information gets lost somehow?
> > I use dmd-1.007 (tried with 1.005 too), build the library with rebuild-0.12.
> > Maybe I should say that I use derelict too, but the error also occurs when
> > toString is called before any derelict-function.
> > 
> > I will try to further reduce the example, maybe later today.
> > 
> > Henning
> 
> You mentioned a library...  If I remember correctly (standard disclaimers apply), then templates are NOT compiled into a library.
> 
> For example, let's say you compiled the following file into a library:
> 
> struct Foo(T)
> {
>     void bar(T value)
>     {
>         writefln("%s", value);
>     }
> }
> 
> And then used it like so:
> 
> void main()
> {
>     Foo!(int) x;
>     x.bar(42);
> }
> 
> And finally compiled it like thus:
> 
>     dmd FooLib.lib main.d
> 
> This would fail since FooLib.lib doesn't actually *have* the implementation of Foo in it.  In order for D to compile a templated struct or class into a library, it would need to compile it for every possible type, which obviously isn't going to happen.

Sounds logical to me, but atm the only type I use for T is int
and the template is instantiated in the library so the version used should be
implemented.
Calling other methods seems to work, too.

> If you want to use templates in a library, you *need* to ship and compile against the source code, not against a precompiled library.  The one exception to this is that it should work for any templates you've explicitly instantiated. So, if you append this to Foo's source file:
> 
>   alias Foo!(int) FooInt;
> 
> then it should work.

And that's what I'm doing, too. So no problem here. Ill now start to find a minimal example of the problem.

Henning
March 01, 2007
O
> And finally compiled it like thus:
> 
>     dmd FooLib.lib main.d
> 
> This would fail since FooLib.lib doesn't actually *have* the implementation of Foo in it.  In order for D to compile a templated struct or class into a library, it would need to compile it for every possible type, which obviously isn't going to happen.

The more I play around with my code the more I think you are right.
But I dont understand why I dont get an error at compile time but at
runtime?
Shouldnt the compiler already see if the template instantiation
is available or not in the linking step?

> If you want to use templates in a library, you *need* to ship and compile against the source code, not against a precompiled library.  The one exception to this is that it should work for any templates you've explicitly instantiated. So, if you append this to Foo's source file:
> 
>   alias Foo!(int) FooInt;
> 
> then it should work.

The problem occurs also when the "main module" does not call any template
function but only code from inside the library does.
Can you explain that with your theory?
What would be the solution?

Henning
« First   ‹ Prev
1 2