· Overview · D for Win32 · Win32 DLLs in D · C .h to D Modules · FAQ · Style Guide · Example: wc · Future · D Change Log · Tech Tips · Glossary · Acknowledgements Tools · DMD D Compiler · GDC D Compiler · Linker · Profiler Community · News Digest · News · Forum · Announcements · Learn · D links Archives · digitalmars.D · digitalmars.D.dtl · digitalmars.D.announce · digitalmars.D.learn · digitalmars.D.bugs · D.gnu · Old D |
FAQThe same questions keep cropping up, so the obvious thing to do is prepare a FAQ.
Why the name D?The original name was the Mars Programming Language. But my friends kept calling it D, and I found myself starting to call it D. The idea of D being a successor to C goes back at least as far as 1988, as in this thread.Where can I get a D compiler?Right here.Is there a linux port of D?Yes, the D compiler includes a linux version.Is there a GNU version of D?Yes, David Friedman has integrated the D frontend with GCC.How do I write my own D compiler for CPU X?Burton Radons has written a back end. you can use as a guide.Where can I get a GUI library for D?Since D can call C functions, any GUI library with a C interface is accessible from D. Various D GUI libraries and ports can be found at AvailableGuiLibraries.Where can I get an IDE for D?LEDS is a D language editor for Linux.What about templates?D now supports advanced templates.Why emphasize implementation ease?Isn't ease of use for the user of the language more important? Yes, it is. But a vaporware language is useless to everyone. The easier a language is to implement, the more robust implementations there will be. In C's heyday, there were 30 different commericial C compilers for the IBM PC. Not many made the transition to C++. In looking at the C++ compilers on the market today, how many years of development went into each? At least 10 years? Programmers waited years for the various pieces of C++ to get implemented after they were specified. If C++ was not so enormously popular, it's doubtful that very complex features like multiple inheritance, templates, etc., would ever have been implemented.I suggest that if a language is easier to implement, then it is likely also easier to understand. Isn't it better to spend time learning to write better programs than language arcana? If a language can capture 90% of the power of C++ with 10% of its complexity, I argue that is a worthwhile tradeoff. Why is [expletive deleted] printf in D?printf is not typesafe. It's old fashioned. It's not object-oriented. It's not usable with user-defined types. printf is guilty as charged. But it's just so darned useful. Nothing beats it for banging out a quick dump of a value when debugging.Note: printf is actually not really part of D anyway, but since D provides easy access to C's runtime library, D gets it when needed. Will D be open source?The front end for D is open source, and the source comes with the compiler. There is a SourceForge project underway to create a Gnu implementation of D from this.Why fall through on switch statements?Many people have asked for a requirement that there be a break between cases in a switch statement, that C's behavior of silently falling through is the cause of many bugs.The reason D doesn't change this is for the same reason that integral promotion rules and operator precedence rules were kept the same - to make code that looks the same as in C operate the same. If it had subtly different semantics, it will cause frustratingly subtle bugs. Why should I use D instead of Java?D is distinct from Java in purpose, philosophy and reality. See this comparison.Java is designed to be write once, run everywhere. D is designed for writing efficient native system apps. Although D and Java share the notion that garbage collection is good and multiple inheritance is bad <g>, their different design goals mean the languages have very different feels. Doesn't C++ support strings, bit arrays, etc. with STL?In the C++ standard library are mechanisms for doing strings, bit arrays, dynamic arrays, associative arrays, bounds checked arrays, and complex numbers.Sure, all this stuff can be done with libraries, following certain coding disciplines, etc. But you can also do object oriented programming in C (I've seen it done). Isn't it incongruous that something like strings, supported by the simplest BASIC interpreter, requires a very large and complicated infrastructure to support? Just the implementation of a string type in STL is over two thousand lines of code, using every advanced feature of templates. How much confidence can you have that this is all working correctly, how do you fix it if it is not, what do you do with the notoriously inscrutable error messages when there's an error using it, how can you be sure you are using it correctly (so there are no memory leaks, etc.)? D's implementation of strings is simple and straightforward. There's little doubt how to use it, no worries about memory leaks, error messages are to the point, and it isn't hard to see if it is working as expected or not. Can't garbage collection be done in C++ with an add-on library?Yes, I use one myself. It isn't part of the language, though, and requires some subverting of the language to make it work. Using gc with C++ isn't for the standard or casual C++ programmer. Building it into the language, like in D, makes it practical for everyday programming chores.GC isn't that hard to implement, either, unless you're building one of the more advanced ones. But a more advanced one is like building a better optimizer - the language still works 100% correctly even with a simple, basic one. The programming community is better served by multiple implementations competing on quality of code generated rather than by which corners of the spec are implemented at all. Can't unit testing be done in C++ with an add-on library?Sure. Try one out and then compare it with how D does it. It'll be quickly obvious what an improvement building it into the language is.Why have an asm statement in a portable language?An asm statement allows assembly code to be inserted directly into a D function. Assembler code will obviously be inherently non-portable. D is intended, however, to be a useful language for developing systems apps. Systems apps almost invariably wind up with system dependent code in them anyway, inline asm isn't much different. Inline asm will be useful for things like accessing special CPU instructions, accessing flag bits, special computational situations, and super optimizing a piece of code.Before the C compiler had an inline assembler, I used external assemblers. There was constant grief because many, many different versions of the assembler were out there, the vendors kept changing the syntax of the assemblers, there were many different bugs in different versions, and even the command line syntax kept changing. What it all meant was that users could not reliably rebuild any code that needed assembler. An inline assembler provided reliability and consistency. What is the point of 80 bit reals?More precision enables more accurate floating point computations to be done, especially when adding together large numbers of small real numbers. Prof. Kahan, who designed the Intel floating point unit, has an eloquent paper on the subject.How do I do anonymous struct/unions in D?struct Foo { union { int a; int b; } struct { int c; int d; } } void main() { Foo f; printf("Foo.size = %d, a.offset = %d, b.offset = %d, c.offset = %d, d.offset = %d\n", f.size, 0, &f.b - &f.a, &f.c - &f.a, &f.d - &f.a); } How do I get printf() to work with strings?In C, the normal way to printf a string is to use the %s format:char s[8]; strcpy(s, "foo"); printf("string = '%s'\n", s);Attempting this in D, as in: char[] s; s = "foo"; printf("string = '%s'\n", s);usually results in garbage being printed, or an access violation. The cause is that in C, strings are terminated by a 0 character. The %s format prints until a 0 is encountered. In D, strings are not 0 terminated, the size is determined by a separate length value. So, strings are printf'd using the %.*s format: char[] s; s = "foo"; printf("string = '%.*s'\n", s);which will behave as expected. Remember, though, that printf's %.*s will print until the length is reached or a 0 is encountered, so D strings with embedded 0's will only print up to the first 0. Why are floating point values default initialized to nan rather than 0?A floating point value, if no explicit initializer is given, is initialized to nan (Not A Number):double d; // d is set to double.nanNan's have the interesting property in that whenever a nan is used as an operand in a computation, the result is a nan. Therefore, nan's will propagate and appear in the output whenever a computation made use of one. This implies that a nan appearing in the output is an unambiguous indication of the use of an uninitialized variable. If 0.0 was used as the default initializer for floating point values, its effect can easily be unnoticed in the output, and so if the default initializer was unintended, the bug may go unrecognized. The default initializer value is not meant to be a useful value, it is meant to expose bugs. Nan fills that role well. But surely the compiler can detect and issue an error message for variables used that are not initialized? Most of the time, it can, but not always, and what it can do is dependent on the sophistication of the compiler's internal data flow analysis. Hence, relying on such is unportable and unreliable. Because of the way CPUs are designed, there is no nan value for integers, so D uses 0 instead. It doesn't have the advantages of error detection that nan has, but at least errors resulting from unintended default initializations will be consistent and therefore more debuggable. Why is overload the assignment operator not supported?Most of the assignment operator overloading in C++ seems to be needed to just keep track of who owns the memory. So by using reference types coupled with GC, most of this just gets replaced with copying the reference itself. For example, given an array of class objects, the array's contents can be moved, sorted, shifted, etc., all without any need for overloaded assignments. Ditto for function parameters and return values. The references themselves just get moved about. There just doesn't seem to be any need for copying the entire contents of one class object into another pre-existing class object.Sometimes, one does need to create a copy of a class object, and for that one can still write a copy constructor in D, but they just don't seem to be needed remotely as much as in C++. Structs, being value objects, do get copied about. A copy is defined in D to be a bit copy. I've never been comfortable with any object in C++ that does something other than a bit copy when copied. Most of this other behavior stems from that old problem of trying to manage memory. Absent that, there doesn't seem to be a compelling rationale for having anything other than a bit copy. The '~' is not on my keyboard?On PC keyboards, hold down the [Alt] key and press the 1, 2, and 6 keys in sequence on the numeric pad. That will generate a '~' character.Can I link in C object files created with another compiler?DMD produces OMF (Microsoft Object Module Format) object files while other compilers such as VC++ produce COFF object files. DMD's output is designed to work with DMC, the Digital Mars C compiler, which also produces object files in OMF format.The OMF format that DMD uses is a Microsoft defined format based on an earlier Intel designed one. Microsoft at one point decided to abandon it in favor of a Microsoft defined variant on COFF. Using the same object format doesn't mean that any C library in that format will successfully link and run. There is a lot more compatibility required - such as calling conventions, name mangling, compiler helper functions, and hidden assumptions about the way things work. If DMD produced Microsoft COFF output files, there is still little chance that they would work successfully with object files designed and tested for use with VC. There were a lot of problems with this back when Microsoft's compilers did generate OMF. Having a different object file format makes it helpful in identifying library files that were not tested to work with DMD. If they are not, weird problems would result even if they successfully managed to link them together. It really takes an expert to get a binary built with a compiler from one vendor to work with the output of another vendor's compiler. That said, the linux version of DMD produces object files in the ELF format which is standard on linux, and it is specifically designed to work with the standard linux C compiler, gcc. There is one case where using existing C libraries does work - when those libraries come in the form of a DLL conforming to the usual C ABI interface. The linkable part of this is called an "import library", and Microsoft COFF format import libraries can be successfully converted to DMD OMF using the coff2omf tool. |
Add feedback and comments regarding this page.