digitalmars.D - Biggest problems w/ D
- C. Dunn <cdunn2001 gmail.com> Aug 09 2007
- Jascha Wetzel <firstname mainia.de> Aug 09 2007
- Robert Fraser <fraserofthenight gmail.com> Aug 09 2007
- Kirk McDonald <kirklin.mcdonald gmail.com> Aug 09 2007
- Tristam MacDonald <swiftcoder gmail.com> Aug 09 2007
- "Craig Black" <craigblack2 cox.net> Aug 09 2007
- Gilles G. <schaouette free.fr> Aug 10 2007
- Paul Findlay <r.lph50+d gmail.com> Aug 10 2007
- Gilles G. <schaouette free.fr> Aug 10 2007
- Paul Findlay <r.lph50+d gmail.com> Aug 10 2007
- Gilles G. <schaouette free.fr> Aug 10 2007
- Paul Findlay <r.lph50+d gmail.com> Aug 10 2007
- Radu <radu.racariu void.space> Aug 10 2007
- BCS <ao pathlink.com> Aug 10 2007
- C. Dunn <cdunn2001 gmail.com> Aug 10 2007
- BCS <ao pathlink.com> Aug 10 2007
- Bill Baxter <dnewsgroup billbaxter.com> Aug 09 2007
- renoX <renosky free.fr> Aug 09 2007
- Henning Hasemann <hhasemann web.de> Aug 10 2007
- Frank Benoit <keinfarbton googlemail.com> Aug 10 2007
- "Alvaro GP" <alvaro liteapplications.com> Aug 10 2007
- Stephen Waits <steve waits.net> Aug 12 2007
After converting a large, system-level program to D, I can name the biggest problems: 1) No stack-trace on exceptions. This makes contract programming a mere QA test, rather than a useful debugging tool. 2) No 64-bit support. This not only limits memory usage, but also causes 2x runtime on my AMD processor. My D code is the same speed as my 32-bit C++ code, but both are 2x slower than 64-bit C++ code. Same compiler. Same machine. 3) Lack of forward declarations. The compiler figures everything out in simple cases, but it gets very confused with templates. That dramatically hurts the genericity of D, since it limits what templates can do. One nice use of templates in C++ is to set a static variable on a type, as a sort of "property" with high-speed access. With D, I have accomplished this only by putting all templates in the same file. This problem also causes the compiler to depend on the order of files on the command-line. 4) Not enough help for converting between D strings and C char*. There must be conversion functions which work regardless of whether the D string is dynamic or not, and regardless of whether the C char* is null terminated. I'm not sure what the answer is, but this has lead to a large number of runtime bugs for me as a novice. 5) Same syntax structs and classes. This is minor problem, but it is extremely confusing to the novice. A struct and a class are completely different in D, but the fact that I can write code the same to use either one implies too much similarity. It leads to programming errors which easily result in seg-fault. Also, it is too difficult to switch a set of objects from structs to classes or vice versa. I need to be able to do that in order to compare runtimes for various implementations. Again, I don't know the best answer. I love the language as an evolution of C++, so I really hope these problems get ironed out. I could list a *lot* of great things about D!
Aug 09 2007
C. Dunn wrote:1) No stack-trace on exceptions. This makes contract programming a mere QA test, rather than a useful debugging tool.
on windows you can use ddbg (http://ddbg.mainia.de) to get full stack-traces for all exceptions
Aug 09 2007
C. Dunn Wrote:5) Same syntax structs and classes. This is minor problem, but it is extremely confusing to the novice. A struct and a class are completely different in D, but the fact that I can write code the same to use either one implies too much similarity. It leads to programming errors which easily result in seg-fault. Also, it is too difficult to switch a set of objects from structs to classes or vice versa. I need to be able to do that in order to compare runtimes for various implementations. Again, I don't know the best answer.
I agree with the rest of your post, but IMO this would make using classes confusing, C++-style. Structs as value-types and classes as reference-types is one of the hallmarks of D and value types + inheritance just makes everything harder (slicing, etc.), and one of D's advantages is that it's a lot simpler to do what you want without ambiguity. Just my opinion, though. I esp. agree on stack tracing, though. Debuggers are nice, but not everyone runs their code under a debugger all the time. I tried Tango + Flectioned, which ran great under Linux, but since I develop on/for Windows, this isn't helpful.
Aug 09 2007
C. Dunn wrote:4) Not enough help for converting between D strings and C char*. There must be conversion functions which work regardless of whether the D string is dynamic or not, and regardless of whether the C char* is null terminated. I'm not sure what the answer is, but this has lead to a large number of runtime bugs for me as a novice.
The std.string module has the toStringz and toString functions. The toString function simply returns a slice over the C string: char[] toString(char* ptr) { return ptr[0 .. strlen(ptr)]; } The toStringz function simply appends a null character (\0) to the end of the D string: char* toStringz(char[] str) { return (str ~ \0).ptr; } These are very simple operations, and it is fairly easy to adapt them to whatever needs you have.5) Same syntax structs and classes. This is minor problem, but it is extremely confusing to the novice. A struct and a class are completely different in D, but the fact that I can write code the same to use either one implies too much similarity. It leads to programming errors which easily result in seg-fault. Also, it is too difficult to switch a set of objects from structs to classes or vice versa. I need to be able to do that in order to compare runtimes for various implementations. Again, I don't know the best answer.
Structs and classes are very different beasts in D, even if they look the same. However, there are some important differences in their use which should clue you in: Using 'new' on a class gives you a reference, using it on a struct gives you a pointer. Structs are plain ol' data. Saying "SomeStruct s;" gives you an instance you can immediately behind using. You have to use 'new' to get a class instance. Classes have inheritance and all those other object-oriented features, while structs do not. What I am getting at is that whether something should be a class or a struct seems like an important design decision which shouldn't be expected to change after development is well underway. Also, code doesn't really look all that similar when it uses structs vs. classes.I love the language as an evolution of C++, so I really hope these problems get ironed out. I could list a *lot* of great things about D!
-- Kirk McDonald http://kirkmcdonald.blogspot.com Pyd: Connecting D and Python http://pyd.dsource.org
Aug 09 2007
Kirk McDonald wrote:C. Dunn wrote:5) Same syntax structs and classes. This is minor problem, but it is extremely confusing to the novice. A struct and a class are completely different in D, but the fact that I can write code the same to use either one implies too much similarity. It leads to programming errors which easily result in seg-fault. Also, it is too difficult to switch a set of objects from structs to classes or vice versa. I need to be able to do that in order to compare runtimes for various implementations. Again, I don't know the best answer.
Structs and classes are very different beasts in D, even if they look the same. However, there are some important differences in their use which should clue you in: Using 'new' on a class gives you a reference, using it on a struct gives you a pointer. Structs are plain ol' data. Saying "SomeStruct s;" gives you an instance you can immediately behind using. You have to use 'new' to get a class instance. Classes have inheritance and all those other object-oriented features, while structs do not. What I am getting at is that whether something should be a class or a struct seems like an important design decision which shouldn't be expected to change after development is well underway. Also, code doesn't really look all that similar when it uses structs vs. classes.
I don't agree here. I had all my algebraic classes (vectors, matrices, transforms, etc.) as structs, as they needed to be value types, and for performance. However, I had to convert several of the more complex structs to classes instead, when I needed reference semantics. Since structs use a different constructor syntax, along with 'this' versus '*this', it was quite annoying. Since the only difference the original spec highlighted was that one in a reference type, and one a value type, it seems silly to have large syntactical differences between them. In particular, that structs lack meaningful constructors/destructors/copying semantics is *really* annoying. Value types are scoped, so why not let us use that to our advantage?
Aug 09 2007
"Tristam MacDonald" <swiftcoder gmail.com> wrote in message news:f9gm20$2jd6$1 digitalmars.com...Kirk McDonald wrote:C. Dunn wrote:5) Same syntax structs and classes. This is minor problem, but it is extremely confusing to the novice. A struct and a class are completely different in D, but the fact that I can write code the same to use either one implies too much similarity. It leads to programming errors which easily result in seg-fault. Also, it is too difficult to switch a set of objects from structs to classes or vice versa. I need to be able to do that in order to compare runtimes for various implementations. Again, I don't know the best answer.
Structs and classes are very different beasts in D, even if they look the same. However, there are some important differences in their use which should clue you in: Using 'new' on a class gives you a reference, using it on a struct gives you a pointer. Structs are plain ol' data. Saying "SomeStruct s;" gives you an instance you can immediately behind using. You have to use 'new' to get a class instance. Classes have inheritance and all those other object-oriented features, while structs do not. What I am getting at is that whether something should be a class or a struct seems like an important design decision which shouldn't be expected to change after development is well underway. Also, code doesn't really look all that similar when it uses structs vs. classes.
I don't agree here. I had all my algebraic classes (vectors, matrices, transforms, etc.) as structs, as they needed to be value types, and for performance. However, I had to convert several of the more complex structs to classes instead, when I needed reference semantics. Since structs use a different constructor syntax, along with 'this' versus '*this', it was quite annoying. Since the only difference the original spec highlighted was that one in a reference type, and one a value type, it seems silly to have large syntactical differences between them. In particular, that structs lack meaningful constructors/destructors/copying semantics is *really* annoying. Value types are scoped, so why not let us use that to our advantage?
Agreed. I think Walter has plans to add constructors/destructors/copying semantics to structs. It's a welcome change. -Craig
Aug 09 2007
Kirk McDonald Wrote:C. Dunn wrote:4) Not enough help for converting between D strings and C char*. There must be conversion functions which work regardless of whether the D string is dynamic or not, and regardless of whether the C char* is null terminated. I'm not sure what the answer is, but this has lead to a large number of runtime bugs for me as a novice.
The std.string module has the toStringz and toString functions. The toString function simply returns a slice over the C string: char[] toString(char* ptr) { return ptr[0 .. strlen(ptr)]; } The toStringz function simply appends a null character (\0) to the end of the D string: char* toStringz(char[] str) { return (str ~ \0).ptr; } These are very simple operations, and it is fairly easy to adapt them to whatever needs you have.
I have a DLL defining the following (extern) function: extern(Windows) void GetName(char* name) I would just like to put the name of the DLL in the variable name. What I would do in C is something like: extern(Windows) void GetName(char* name) { name = "The DLL name"; } This just won't work in D... My solution for now is the following: extern(Windows) void GetName(char* name) { foreach(ic, c; "The DLL name\0") name[ic]=c; } which is ugly, but do you have a better solution? --Gilles
Aug 10 2007
I would just like to put the name of the DLL in the variable name. What I would do in C is something like: Â Â Â extern(Windows) void GetName(char* name) Â Â Â { Â Â Â Â Â name = "The DLL name"; Â Â Â }
const char[] DLL_NAME = "The DLL name"; extern(Windows) void GetName(char* name) { Â Â name = DLL_NAME.ptr; } work? - Paul
Aug 10 2007
Paul Findlay Wrote:I would just like to put the name of the DLL in the variable name. What I would do in C is something like: Â Â Â extern(Windows) void GetName(char* name) Â Â Â { Â Â Â Â Â name = "The DLL name"; Â Â Â }
const char[] DLL_NAME = "The DLL name"; extern(Windows) void GetName(char* name) { Â Â name = DLL_NAME.ptr; } work?
I tried: const char[15] DLL_NAME="The DLL name"; extern(Windows) void GetName(char* name) { name = DLL_NAME.ptr; }
Aug 10 2007
Unfortunately, no. I tried: const char[15] DLL_NAME="The DLL name";
is the problem), so you could also try: name = "The DLL Name".ptr Sorry about this being the blind leading the blind.. - Paul
Aug 10 2007
Paul Findlay Wrote:Unfortunately, no. I tried: const char[15] DLL_NAME="The DLL name";
is the problem), so you could also try: name = "The DLL Name".ptr Sorry about this being the blind leading the blind..
(In fact I tried const char[15] DLL_NAME="The DLL name\0"; )- Paul
Aug 10 2007
Umm can we review what you are tying to do.. because if its something like
this (C version)
#include <stdio.h>
void GetName(char *name)
{
name = "The right one";
}
int main()
{
char *name = "the original";
GetName(name);
printf("%s\n", name);
}
it will print: the original
If you want name to hold "the right one" it will need to be a pointer to a
pointer:
#include <stdio.h>
void GetName(char **name)
{
*name = "The right one";
}
int main()
{
char *name = "the original";
GetName(&name);
printf("%s\n", name);
// will print: The right one
}
Otherwise, I give up..
Aug 10 2007
is this working for you?
extern(Windows) void GetName(ref char* name)
{
name = "just modified".ptr;
}
void main ()
{
char* cpt = "initial value".ptr;
GetName(cpt);
printf("%s",cpt);
}
Gilles G. wrote:
Kirk McDonald Wrote:
C. Dunn wrote:
4) Not enough help for converting between D strings and C char*.
There must be conversion functions which work regardless of whether
the D string is dynamic or not, and regardless of whether the C char*
is null terminated. I'm not sure what the answer is, but this has
lead to a large number of runtime bugs for me as a novice.
The toString function simply returns a slice over the C string:
char[] toString(char* ptr) {
return ptr[0 .. strlen(ptr)];
}
The toStringz function simply appends a null character (\0) to the end
of the D string:
char* toStringz(char[] str) {
return (str ~ \0).ptr;
}
These are very simple operations, and it is fairly easy to adapt
them to whatever needs you have.
I have a DLL defining the following (extern) function:
extern(Windows) void GetName(char* name)
I would just like to put the name of the DLL in the variable name. What I
would do in C is something like:
extern(Windows) void GetName(char* name)
{
name = "The DLL name";
}
This just won't work in D... My solution for now is the following:
extern(Windows) void GetName(char* name)
{
foreach(ic, c; "The DLL name\0")
name[ic]=c;
}
which is ugly, but do you have a better solution?
--Gilles
Aug 10 2007
Reply to Gilles G.,Kirk McDonald Wrote:C. Dunn wrote:4) Not enough help for converting between D strings and C char*. There must be conversion functions which work regardless of whether the D string is dynamic or not, and regardless of whether the C char* is null terminated. I'm not sure what the answer is, but this has lead to a large number of runtime bugs for me as a novice.
The toString function simply returns a slice over the C string: char[] toString(char* ptr) { return ptr[0 .. strlen(ptr)]; } The toStringz function simply appends a null character (\0) to the end of the D string: char* toStringz(char[] str) { return (str ~ \0).ptr; } These are very simple operations, and it is fairly easy to adapt them to whatever needs you have.
the problems I had with char[] and char*. I have a DLL defining the following (extern) function: extern(Windows) void GetName(char* name) I would just like to put the name of the DLL in the variable name. What I would do in C is something like: extern(Windows) void GetName(char* name) { name = "The DLL name"; } This just won't work in D... My solution for now is the following: extern(Windows) void GetName(char* name) { foreach(ic, c; "The DLL name\0") name[ic]=c; } which is ugly, but do you have a better solution? --Gilles
if you are passing a buffer this should work extern(Windows) GetName(char* buf) // should have length to { static const char[] n = "The DLL name\0"; buf[0..n.length]=n[]; }
Aug 10 2007
Kirk McDonald Wrote:Structs and classes are very different beasts in D, even if they look the same. However, there are some important differences in their use which should clue you in: Using 'new' on a class gives you a reference, using it on a struct gives you a pointer. Structs are plain ol' data. Saying "SomeStruct s;" gives you an instance you can immediately behind using. You have to use 'new' to get a class instance. Classes have inheritance and all those other object-oriented features, while structs do not. What I am getting at is that whether something should be a class or a struct seems like an important design decision which shouldn't be expected to change after development is well underway. Also, code doesn't really look all that similar when it uses structs vs. classes.
When converting C++ to D, the choice of struct or class is not so obvious. struct has performance advantages, and testing may be required to decide whether that advantage is significant in context. I would like to typedef (or alias) like this: struct S{} class C{} version(fast){ alias C Foo; }else{ alias S* Foo; } The problem is that, since S lacks ctor/dtor, I have to rewrite my code substantially. If you doubt the performance difference, try this: static import std.stdio; static import std.c.stdlib; struct A{ int x = 57; void set(int y){ x = y; } }; void foo(uint n){ auto all = new A*[n]; uint c = n; while(c--){ all[c] = new A; } c = n; while(c--){ assert(all[c].x == 57); all[c].set(c); assert(all[c].x == c); } c = n; while(c--){ delete all[c]; } } class B{ int x = 57; void set(int y){ x = y; } }; void bar(uint n){ auto all = new B[n]; uint c = n; while(c--){ all[c] = new B; } c = n; while(c--){ assert(all[c].x == 57); all[c].set(c); assert(all[c].x == c); } c = n; while(c--){ delete all[c]; } } int main(char[][] args) { uint n = 1; if (args.length>1){ n = std.c.stdlib.atoi(args[1].ptr); } //foo(n); bar(n); std.stdio.writefln("Done ", n); return 0; } [Here, I do not need ctors, since I have initializers.] Use either foo() or bar(). With normal compilation, I get a 10% slow-down for the class. With "-O -inline -release", I get 10% to 20%, and it's not even consistent. Sometimes 10% is important, especially for system-level tasks. One could fear an even bigger hit, so the ability to do comparative testing is important. Someone said that Walter is adding ctors to structs. That would help. But note that I cannot write generic code! operator new() returns different things in different situations!! If I try to use an alias or a typedef to switch between A* (pointer to struct A) and B (ref to class B), I cannot call new on the alias: version(A){ alias A* Foo; }else{ alias B Foo; } Foo x = new Foo; This does not work!!!!!!!!!! Hopefully, you can now see the problem. This is a big impediment in converting C++ code to D, and not just b/c of the runtime difference. The natural thing is to convert C-style structs to D structs, using std.c.stdlib.malloc()/free(). Then, during refactoring, a person might say, "Hmmm. Maybe it would be cool to use D classes instead." But the "refactoring" is a huge pain in the arse because of this inconsistency. When Foo is a struct, the syntax should be "new Foo*()", not "new Foo()". That completely solves the problem, but breaks existing code. Solution: "operator New" with a capital N. It's important to recognize that D is just an OK language all by itself. Its great potential comes from its close resemblance to C++, making the transistion possible. Smooth code re-factoring is extemely important if you want C++ coders to adopt D.
Aug 10 2007
Reply to C. Dunn,struct S{} class C{} version(fast){ alias C Foo; }else{ alias S* Foo; } The problem is that, since S lacks ctor/dtor, I have to rewrite my code substantially.
For ctor you could use a static method to wrap the new for both cases. Not vary clean but the performance hit should be the same for both sides. For dtor, no such luck. Then again I have yet to ever use a dtor in D.
Aug 10 2007
C. Dunn wrote:After converting a large, system-level program to D, I can name the biggest problems:
2) No 64-bit support. This not only limits memory usage, but also causes 2x runtime on my AMD processor. My D code is the same speed as my 32-bit C++ code, but both are 2x slower than 64-bit C++ code. Same compiler. Same machine.
Been asked for many-a-time. I believe GDC, now supports 64-bit compilation. http://dgcc.sourceforge.net/ The problem is that the linker used by DMD is some ancient thing written in assembly that ain't never gonna get upgraded to 64bit. A new linker must be found or written eventually. Unless someone interested in helping with that comes out of the woodwork, it's probably going to mean a 6-12 month halt in progress for D as Walter goes off to write a new linker. I think few people want that to happen to D, at least not until the language has all its issues pretty much worked out.3) Lack of forward declarations. The compiler figures everything out in simple cases, but it gets very confused with templates. That dramatically hurts the genericity of D, since it limits what templates can do. One nice use of templates in C++ is to set a static variable on a type, as a sort of "property" with high-speed access. With D, I have accomplished this only by putting all templates in the same file. This problem also causes the compiler to depend on the order of files on the command-line.
Been asked for many-a-time. I think the problem is again the black-box linker that no one knows how to fix. --bb
Aug 09 2007
C. Dunn a écrit :After converting a large, system-level program to D, I can name the biggest problems:
2) No 64-bit support. This not only limits memory usage, but also causes 2x runtime on my AMD processor. My D code is the same speed as my 32-bit C++ code, but both are 2x slower than 64-bit C++ code. Same compiler. Same machine.
2x? Your code must do a lot of 64b computation! When the AMD64 was released benchmarks made showed at best a 20% improvement, which is quite a lot to get with a simple recompilation assuming the code is 64b clean of course but is nowhere 2x. Either your code makes a lot of 64b computations or there are issue on the 32b version of your C++ code. That said, its a problem with DMD not with D, if memory serves GDC supports 64b code generation. renoX
Aug 09 2007
Been asked for many-a-time. I believe GDC, now supports 64-bit compilation. http://dgcc.sourceforge.net/
At least for me 64 bit gdc works very fine atm (on linux).Been asked for many-a-time. I think the problem is again the black-box linker that no one knows how to fix.
Would it be easier/less work to have dmd output the "standard" windows object format then write a new linker? (I dont remember the exact name of that beast) I mean finding linkers for that wouldnt be too hard (iirc lcc has one, there is a free one from M$ etc...) and on linux there is no problem anyway as the object format is already the "standard one". Henning -- GPG Public Key: http://keyserver.ganneff.de:11371/pks/lookup?op=get&search=0xDDD6D36D41911851 Fingerprint: 344F 4072 F038 BB9E B35D E6AB DDD6 D36D 4191 1851
Aug 10 2007
C. Dunn schrieb:1) No stack-trace on exceptions. This makes contract programming a mere QA test, rather than a useful debugging tool.
Since I use flectioned, i have stack traces for exceptions and segmentation faults. I havn't tested it with DBC.
Aug 10 2007
Sorry for being a little offtopic, but I saw your post and I was wondering if you are Corbin Dunn, ex Borland employee. It's pretty exciting to see you using the D language. I'm sure that this encourages us to embrace it above the difficulties.
Aug 10 2007
Alvaro GP wrote:Sorry for being a little offtopic, but I saw your post and I was wondering if you are Corbin Dunn, ex Borland employee. It's pretty exciting to see you using the D language. I'm sure that this encourages us to embrace it above the difficulties.
If it is the same guy, he works for Apple now. I'd love to hear we have a D Evangelist (or two) in Cupertino. Also looks like a fellow ERAU dropout. Anyway, here's his site: http://www.corbinstreehouse.com/ --Steve
Aug 12 2007









Jascha Wetzel <firstname mainia.de> 