Thread overview | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
February 28, 2007 toString() on struct template | ||||
---|---|---|---|---|
| ||||
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 Re: toString() on struct template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Henning Hasemann | 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 Re: toString() on struct template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Henning Hasemann | 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 Re: toString() on struct template | ||||
---|---|---|---|---|
| ||||
Posted in reply to mario pernici | 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 Re: toString() on struct template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Reiner Pope | 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 Re: toString() on struct template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Henning Hasemann | 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 Re: toString() on struct template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Henning Hasemann | 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 Re: toString() on struct template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Henning Hasemann | 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 Re: toString() on struct template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | 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 Re: toString() on struct template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | 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 |
Copyright © 1999-2021 by the D Language Foundation