www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - DMD 0.118 release

reply "Walter" <newshound digitalmars.com> writes:
Fixed what I broke in 0.117.

http://www.digitalmars.com/d/changelog.html
Mar 12 2005
next sibling parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Walter wrote:

 Fixed what I broke in 0.117.
 
 http://www.digitalmars.com/d/changelog.html

Thanks! It now builds both, without problems. (recompiles both versions of Phobos, that was) --anders
Mar 12 2005
prev sibling next sibling parent reply "Carlos Santander B." <csantander619 gmail.com> writes:
DMDScript compiles fine, but optlink complains when linking ds.exe 
because of some undefined symbols. I haven't tried on linux yet, and I 
don't know if it also happened with 0.117 because I didn't try it.

_______________________
Carlos Santander Bernal
Mar 13 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"Carlos Santander B." <csantander619 gmail.com> wrote in message
news:d11mge$2bg9$1 digitaldaemon.com...
 DMDScript compiles fine, but optlink complains when linking ds.exe
 because of some undefined symbols. I haven't tried on linux yet, and I
 don't know if it also happened with 0.117 because I didn't try it.

It'll link in if protoerror.obj is specifically specified on the command line. I'll fix it.
Mar 13 2005
parent reply "Carlos Santander B." <csantander619 gmail.com> writes:
Walter wrote:
 "Carlos Santander B." <csantander619 gmail.com> wrote in message
 news:d11mge$2bg9$1 digitaldaemon.com...
 
DMDScript compiles fine, but optlink complains when linking ds.exe
because of some undefined symbols. I haven't tried on linux yet, and I
don't know if it also happened with 0.117 because I didn't try it.

It'll link in if protoerror.obj is specifically specified on the command line. I'll fix it.

This has been a problem with templates for a while, and I hope you address it fully because it's really complex. When having many templates in different modules, the linker complains about undefined symbols and you have to link in the oddest object files so it can go on. Obviously, the problem vanishes when you try to reduce it to send a bug. _______________________ Carlos Santander Bernal
Mar 13 2005
parent "Walter" <newshound digitalmars.com> writes:
"Carlos Santander B." <csantander619 gmail.com> wrote in message
news:d12r1b$bsp$1 digitaldaemon.com...
 Walter wrote:
 It'll link in if protoerror.obj is specifically specified on the command
 line. I'll fix it.

This has been a problem with templates for a while, and I hope you address it fully because it's really complex. When having many templates in different modules, the linker complains about undefined symbols and you have to link in the oddest object files so it can go on. Obviously, the problem vanishes when you try to reduce it to send a bug.

The problem happens when the only thing you're linking from a file is a template expansion.
Mar 13 2005
prev sibling next sibling parent reply Hiroshi Sakurai <Hiroshi_member pathlink.com> writes:
Hi all.

This topic wroten by gears in Japanese D language wiki.

http://f17.aaa.livedoor.jp/~labamba/?BugTrack%2F12
--------
D cant extends a struct,
I think easily exptends a struct of D if it is possible as follows.

test.d

struct Rect : RECT {
private RECT rect;
alias rect.left   left;
alias rect.top    top;
alias rect.right  right;
alias rect.bottom bottom;

int width()  { return right-left; }
int height() { return bottom-top; }
}

PS.
sorry. this English is poor. long sentence is difficult :)

Thanks,
Hiroshi Sakurai.
Mar 13 2005
next sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Hiroshi Sakurai wrote:

 D cant extends a struct,
 I think easily exptends a struct of D if it is possible as follows.
 
 test.d
 
 struct Rect : RECT {
 private RECT rect;
 alias rect.left   left;
 alias rect.top    top;
 alias rect.right  right;
 alias rect.bottom bottom;
 
 int width()  { return right-left; }
 int height() { return bottom-top; }
 }

The ancient method (in C, that is) to "extend" a struct, is to declare the "super" structure as the first member: struct RECT { int left,top,right,bottom; } struct Rect { private RECT rect; int width() { return rect.right-rect.left; } int height() { return rect.bottom-rect.top; } } Then you can still cast a (RECT*) into a (Rect*), for instance. And maybe the syntax you suggest could be introduced for this ? --anders
Mar 13 2005
parent reply Ben Hinkle <Ben_member pathlink.com> writes:
In article <d1257g$2pkj$1 digitaldaemon.com>,
=?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= says...
Hiroshi Sakurai wrote:

 D cant extends a struct,
 I think easily exptends a struct of D if it is possible as follows.
 
 test.d
 
 struct Rect : RECT {
 private RECT rect;
 alias rect.left   left;
 alias rect.top    top;
 alias rect.right  right;
 alias rect.bottom bottom;
 
 int width()  { return right-left; }
 int height() { return bottom-top; }
 }

The ancient method (in C, that is) to "extend" a struct, is to declare the "super" structure as the first member: struct RECT { int left,top,right,bottom; } struct Rect { private RECT rect; int width() { return rect.right-rect.left; } int height() { return rect.bottom-rect.top; } } Then you can still cast a (RECT*) into a (Rect*), for instance. And maybe the syntax you suggest could be introduced for this ? --anders

Presumably the OP wants Rect to be implicitly converted to RECT, too. It might be fun to explore expanding the role of structs to have some C++-like behaviors like constructors and "inheritance" (but no vtables). -Ben
Mar 13 2005
next sibling parent reply pragma <pragma_member pathlink.com> writes:
In article <d12atd$2vo8$1 digitaldaemon.com>, Ben Hinkle says...
 [examples cut for brevity]

Presumably the OP wants Rect to be implicitly converted to RECT, too. It might
be fun to explore expanding the role of structs to have some C++-like behaviors
like constructors and "inheritance" (but no vtables).

Makes sense to me. Structs in D have been relegated to an "advanced" programming technique anyway, for a multitude of reasons (pass-by-value, pointers, etc). I don't see any reason why adding static casting, and compile-time inheritance isn't doable. It certainly couldn't make them any harder to use. struct Rect{ uint top,left,height,width; } struct MyRect: Rect{ byte color_red,color_blue,color_green,color_alpha; } void main(){ MyRect* mr = new MyRect(); Rect *r = cast(Rect*)mr; // compile-time type checking only (static cast) } I can even see interfaces thrown into the mix too, again, as a compile-time inheritance mechanism. - EricAnderton at yahoo
Mar 13 2005
parent reply Ben Hinkle <Ben_member pathlink.com> writes:
Makes sense to me.  Structs in D have been relegated to an "advanced"
programming technique anyway, for a multitude of reasons (pass-by-value,
pointers, etc).

Why do you say structs are advanced? They are simpler than classes. To me they are a step between basic types like ints and doubles and classes.
I don't see any reason why adding static casting, and compile-time inheritance
isn't doable.  It certainly couldn't make them any harder to use.

struct Rect{
uint top,left,height,width;
}

struct MyRect: Rect{
byte color_red,color_blue,color_green,color_alpha;
}

void main(){
MyRect* mr = new MyRect();
Rect *r = cast(Rect*)mr;  // compile-time type checking only (static cast)
}

Do you see the compile-time check as disallowing non up-casts? My first assumtion was that casting stays the same - no checks at all - but I can see how the analogy to class casting would be nice, too.
I can even see interfaces thrown into the mix too, again, as a compile-time
inheritance mechanism.

- EricAnderton at yahoo

I think the only danger with adding inheritance-like features to structs is that people would confuse structs with classes. Plus we should figure out a way to avoid slicing structs. Maybe implicit upcasts would have to get the boot.
Mar 13 2005
parent reply pragma <pragma_member pathlink.com> writes:
In article <d12ol1$a5u$1 digitaldaemon.com>, Ben Hinkle says...
Makes sense to me.  Structs in D have been relegated to an "advanced"
programming technique anyway, for a multitude of reasons (pass-by-value,
pointers, etc).

Why do you say structs are advanced? They are simpler than classes. To me they are a step between basic types like ints and doubles and classes.

I guess it's really a matter of opinion. D to me seems to cater to classes with more features and a cleaner syntax for reference semantics. This leaves structs as a sort of "ugly-duckling" by relying on pointers to get the same job done.
Do you see the compile-time check as disallowing non up-casts? My first
assumtion was that casting stays the same - no checks at all - but I can see how
the analogy to class casting would be nice, too.

Disallowing downcasts (parent to child) is probably the only sane approach as there's no way to guarantee the layout of the struct due to aliasing. Of course one could always cast through void* via Walter's "static cast idiom", which plays well with everything else.
I think the only danger with adding inheritance-like features to structs is that
people would confuse structs with classes. Plus we should figure out a way to
avoid slicing structs. Maybe implicit upcasts would have to get the boot.

I agree that it would lend to some confusion. The concept would place a burden of education on the would-be programmer first, but not without granting him/her some useful (and optional) features. Implicit upcasts should be well within reach of this idea: Given:
 struct Base{}
 struct Child: Base{}
 struct Grandchild: Child{}
 Child a;

Implicit cast followed by value-copy of Base-only members:
 Base b = a;

Implicit cast to pointer type:
 Base* bp = &a;

Its the "lvalue type member copy" feature that would really make this useful IMO. Everything else is cake. Since the type information doesn't exist at runtime, you cannot perform implicit downcasts. Since all you have are either raw pointers or values, the workarounds are unsafe, ugly and ill-advised: Explicit downcast via static cast idiom (dangerous)
 Child* c = cast(Child*)cast(void*)bp;

Explicit downcast followed by value copy (very dangerous)
 Child d = *(cast(Child*)cast(void*)bp);

- EricAnderton at yahoo
Mar 13 2005
parent reply Ben Hinkle <Ben_member pathlink.com> writes:
Makes sense to me.  Structs in D have been relegated to an "advanced"
programming technique anyway, for a multitude of reasons (pass-by-value,
pointers, etc).

Why do you say structs are advanced? They are simpler than classes. To me they are a step between basic types like ints and doubles and classes.

I guess it's really a matter of opinion. D to me seems to cater to classes with more features and a cleaner syntax for reference semantics. This leaves structs as a sort of "ugly-duckling" by relying on pointers to get the same job done.

oh, ok. I guess I'd say structs should be handled by value most of the time. That is, I wouldn't use a struct to get the same job done as a class - I'd use a class. But I agree pointers are more common with large structs.
Do you see the compile-time check as disallowing non up-casts? My first
assumtion was that casting stays the same - no checks at all - but I can see how
the analogy to class casting would be nice, too.

Disallowing downcasts (parent to child) is probably the only sane approach as there's no way to guarantee the layout of the struct due to aliasing. Of course one could always cast through void* via Walter's "static cast idiom", which plays well with everything else.

I don't know. I can cast int* to double* without a peep from the compiler. So why can't I cast a Foo* to a Bar*? Who cares if it is an up or down cast - it's just a pointer cast.
Given:
 struct Base{}
 struct Child: Base{}
 struct Grandchild: Child{}
 Child a;

Implicit cast followed by value-copy of Base-only members:
 Base b = a;


To me this one is the scary one. Slicing is a common newbie C++ mistake - and given that classes are passed by reference it would look wierd that assigning to Base would be fine if they were classes but can drop data if they were structs. One should have to work to drop data IMO (eg, by casting to the base or accessing a member). It is tempting to add it, though, given that the OP's request was basically sub-classing in order to add member functions.
Mar 13 2005
parent reply pragma <pragma_member pathlink.com> writes:
In article <d130h8$glu$1 digitaldaemon.com>, Ben Hinkle says...
Disallowing downcasts (parent to child) is probably the only sane approach as
there's no way to guarantee the layout of the struct due to aliasing.  Of course
one could always cast through void* via Walter's "static cast idiom", which
plays well with everything else.

I don't know. I can cast int* to double* without a peep from the compiler. So why can't I cast a Foo* to a Bar*? Who cares if it is an up or down cast - it's just a pointer cast.

The ability to cast any scalar pointer to another seems to be a holdover from C/C++ IMO. If I had to guess, DMD treats int* the same as void*. Honestly, I feel that one's a bug. Your example of casting int* to double* exemplifies that.
Given:
 struct Base{}
 struct Child: Base{}
 struct Grandchild: Child{}
 Child a;

Implicit cast followed by value-copy of Base-only members:
 Base b = a;


To me this one is the scary one. Slicing is a common newbie C++ mistake - and given that classes are passed by reference it would look wierd that assigning to Base would be fine if they were classes but can drop data if they were structs. One should have to work to drop data IMO (eg, by casting to the base or accessing a member). It is tempting to add it, though, given that the OP's request was basically sub-classing in order to add member functions.

Your use of the word 'slicing' in this context threw me for a loop the first time you used it; I kept thinking 'array slicing'. But the thought grew, and suddenly the following was set in my mind:
 Base b = a[Base]; // literally 'slicing' a struct

Which is funky to say the least, but it sort of gets the point across. At least it's more explicit than my earlier suggestion of an implicit cast. Here, we're saying "slice 'a' down to 'Base'" instead of "make 'a' look like 'Base'". Also 'Base' only exists at runtime, so this would play fair with opIndex() and friends. But after all, its just an idea. I personally like this one about as much as the casting examples I drafted earlier. Another side-effect is how overrided base methods are handled since we've done away with vtables.
 Child *c = new Child();
 Base *b = c;
 c.foo(); // calls Child.foo()
 b.foo(); // calls Base.foo()

Its divergent from the assumed class-like behavior since with classes you'd expect c.foo() to be called in both cases. Is this too subtle? ..just covering all the bases. - EricAnderton at yahoo
Mar 13 2005
parent reply Ben Hinkle <Ben_member pathlink.com> writes:
Your use of the word 'slicing' in this context threw me for a loop the first
time you used it; I kept thinking 'array slicing'. 

oops - sorry. 'Slicing' in C++ is when you, for example, pass a derviced class to a function taking a base class and all the derived-specific data of the object is 'sliced' off. People expect that passing a derived class around would preserve the derived data. Hence why pointers to structs are so important in C++.
Mar 14 2005
parent pragma <pragma_member pathlink.com> writes:
In article <d1403i$1hgr$1 digitaldaemon.com>, Ben Hinkle says...
Your use of the word 'slicing' in this context threw me for a loop the first
time you used it; I kept thinking 'array slicing'. 

oops - sorry. 'Slicing' in C++ is when you, for example, pass a derviced class to a function taking a base class and all the derived-specific data of the object is 'sliced' off. People expect that passing a derived class around would preserve the derived data. Hence why pointers to structs are so important in C++.

Okay, gotcha. So the question is, is slicing back to a base struct type allowable, and if so, what is the syntax? Should it be a part of an implicit upcast or use my slice (mystruct[BaseType]) notation (or something else)? Both have merits. I'm just wondering which, if either, is right for D. - EricAnderton at yahoo
Mar 14 2005
prev sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Ben Hinkle wrote:

 Presumably the OP wants Rect to be implicitly converted to RECT, too.

That doesn't work if "Rect" adds any new fields, though ? But as long as Rect.sizeof == RECT.sizeof, just cast away...
 It might
 be fun to explore expanding the role of structs to have some C++-like behaviors
 like constructors and "inheritance" (but no vtables).

IMHO, if you want classes you know where to find them... Adding methods to structs is something of an ugly hack. --anders
Mar 14 2005
parent reply Derek Parnell <derek psych.ward> writes:
On Mon, 14 Mar 2005 11:25:07 +0100, Anders F Björklund wrote:

 Ben Hinkle wrote:
 
 Presumably the OP wants Rect to be implicitly converted to RECT, too.

That doesn't work if "Rect" adds any new fields, though ? But as long as Rect.sizeof == RECT.sizeof, just cast away...
 It might
 be fun to explore expanding the role of structs to have some C++-like behaviors
 like constructors and "inheritance" (but no vtables).

IMHO, if you want classes you know where to find them... Adding methods to structs is something of an ugly hack.

Why? Are you suggesting that there is something fundamentally wrong with entities, which are passed as values and not as references, having methods? I can't see what is so wrong with that concept. -- Derek Parnell Melbourne, Australia 14/03/2005 10:07:54 PM
Mar 14 2005
parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Derek Parnell wrote:

IMHO, if you want classes you know where to find them...
Adding methods to structs is something of an ugly hack.

Why? Are you suggesting that there is something fundamentally wrong with entities, which are passed as values and not as references, having methods? I can't see what is so wrong with that concept.

No, that's OK... Just that when you start to add inheritance and constructors and the rest of the class stuff it's "too much"? Then again, structs and even typedefs having methods do have some neat uses for extending OS types or validating custom ones. I just don't like OOP code using struct for "performance reasons". But that could just be since I'm used to Java, and not to C++... ? But I would still like my D structs to be more like they are in C, possibly with some methods or even "extends" sugar sprinkled on top? A little context and code examples could probably help the discussion. --anders
Mar 14 2005
parent reply Ben Hinkle <Ben_member pathlink.com> writes:
Then again, structs and even typedefs having methods do have
some neat uses for extending OS types or validating custom ones.

A typedef can have methods? How do you do that?
I just don't like OOP code using struct for "performance reasons".
But that could just be since I'm used to Java, and not to C++... ?

Besides performance structs can have a more natural semantics. See example below.
But I would still like my D structs to be more like they are in C,
possibly with some methods or even "extends" sugar sprinkled on top?

That's the idea. They already have methods, though, so that part is done.
A little context and code examples could probably help the discussion.

Instead of Rect let's take an even smaller class Point. In MinWin I define for each OS an alias NativePoint for the native point type (POINT, XPoint, GdkPoint). Then the MinWin Point is # struct Point { # NativePoint native; # int x(){return native.x;} # int y(){return native.y;} # ... setters... # char[] toString() {...} # Point opAdd(Point b) {...} # ... etc ... # } # Point toPoint(NativePoint p) {...} So that to pass a Point in variable pt to a function that takes a POINT, for example, you would say pt.native. If I had been able to say # struct Point : NativePoint { # functions specific to MinWin... # } and have the conversions be implicit and the x() and y() properties inherited it would make for less code for me to type. Also the convertion function toPoint could possibly go. Given that Point is a small struct it isn't a big deal to explicitly type everything out and one could argue that this would be the case for most structs.
Mar 14 2005
parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Ben Hinkle wrote:

Then again, structs and even typedefs having methods do have
some neat uses for extending OS types or validating custom ones.

A typedef can have methods? How do you do that?

Close your eyes and wish real hard :-) (it was a suggestion) See http://www.prowiki.org/wiki4d/wiki.cgi?Typedef-Block
 and have the conversions be implicit and the x() and y() properties inherited
it
 would make for less code for me to type. Also the convertion function toPoint
 could possibly go. Given that Point is a small struct it isn't a big deal to
 explicitly type everything out and one could argue that this would be the case
 for most structs. 

Good example, that seems to be a good use of struct "inheritance". Just syntactical sugar, but the good and sweet kind thereof... --anders
Mar 14 2005
prev sibling parent <Altair_liu hotmail.com> writes:
"Hiroshi Sakurai" <Hiroshi_member pathlink.com> wrote:

 struct Rect : RECT {
 private RECT rect;
 alias rect.left   left;
 alias rect.top    top;
 alias rect.right  right;
 alias rect.bottom bottom;

 int width()  { return right-left; }
 int height() { return bottom-top; }
 }

This can not work at all, since alias is used to assign an alias of "type". Obviously, left is not a type. Compiler will indicate the error like this : "rect.left is used as a type" Shawn Liu
Mar 14 2005
prev sibling parent Ben Hinkle <Ben_member pathlink.com> writes:
In article <d1080p$10j6$1 digitaldaemon.com>, Walter says...
Fixed what I broke in 0.117.

http://www.digitalmars.com/d/changelog.html

On Windows that bug about multiple definitions is gone but on Linux I get it. For example take the same mod1.d mod2.d and mod3.d and dmd -c mod1.d etc dmd mod1.o mod2.o mod3.o gcc mod1.o mod2.o mod3.o -o mod1 -lphobos -lpthread -lm mod3.o(.bss+0x0): multiple definition of `_init_4mod15Foo_i3Foo' mod2.o(.bss+0x0): first defined here collect2: ld returned 1 exit status It works ok if I just run "dmd mod1.d mod2.d mod3.d"
Mar 13 2005