Oh, and virtual-by-default... completely unacceptable for a systems language. most functions are NOT virtual, and finding the false-virtuals while optimising will be extremely tedious and time consuming. Worse, if libraries contain false virtuals, there's good chance I may not be able to use said library on certain architectures (PPC, ARM in particular). Terrible decision... completely contrary to modern hardware design and trends. Why invent a 'new' language for 10 year old hardware?

On 4 January 2012 11:39, Manu <turkeyman@gmail.com> wrote:
This conversation has meandered into one very specific branch, but I just want to add my 2c to the OP.
I agree, I want D to be a useful systems language too. These are my issues to that end:

 * __forceinline ... I wasn't aware this didn't exist... and yes, despite all this discussion, I still depend on this all the time. People are talking about implementing forceinline by immitating macros using mixins... crazy? Here's a solid reason I avoid mixins or procedurally generated code (and the preprocessor in C for that matter, in favour of __forceinline): YOU CAN DEBUG IT. In an inline function, the code exists in the source file, just like any other function, you can STEP THE DEBUGGER through it, and inspect the values easily. This is an underrated requirement. I would waste hours on many days if I couldn't do this. I would only ever use string mixins for the most obscure uses, preferring inline functions for the sake of debugging 99% of the time.

 * vector type ... D has exactly no way to tell the compiler to allocate 128bit vector registers, load/store, and pass then to/from functions. That is MOST of the register memory on virtually every modern processor, and D can't address it... wtf?

 * inline assembler needs pseudo registers ... The inline assembler is pretty crap, immitating C which is out-dated. Registers in assembly code should barely ever be addressed directly, they should only be addressed by TYPE, allowing the compiler to allocate available registers (and/or manage storing the the stack where required) as with any other code. Inline assembly without pseudo-registers is almost always an un-optimisation, and this is also the reason why almost all C programmers use hardware opcode intrinsics instead of inline assembly. There is no way without using intrinsics in C to allow the compiler to perform optimal register allocation, and this is still true for D, and in my opinion, just plain broken.

 * __restrict ... I've said this before, but not being able to hint that the compiler ignore possible pointer aliasing is a big performance problem, especially when interacting with C libs.

 * multiple return values (in registers) ... (just because I opened a topic about it before) This saves memory accesses in common cases where i want to return (x, y), or (retVal, errorCode) for instance.

Walter made an argument "The same goes for all those language extensions you mentioned. Those are not part of Standard C. They are vendor extensions. Does that mean that C is not actually a systems language? No."
This is absurd... are you saying that you expect Iain to add these things to GDC to that people can use them, and then create incompatible D code with the 'standard' compiler?
Why would you intentionally fragment the compiler support of language features rather than just making trivial (but important) features that people do use part of the language?

This is a great example of why C is shit, and a good example of why I'm interested in D at all...

On 29 December 2011 13:19, Vladimir Panteleev <vladimir@thecybershadow.net> wrote:
On Thursday, 29 December 2011 at 09:16:23 UTC, Walter Bright wrote:
Are you a ridiculous hacker? Inline x86 assembly that the compiler actually understands in 32 AND 64 bit code, hex string literals like x"DE ADB EEF" where spacing doesn't matter, the ability to set data alignment cross-platform with type.alignof = 16, load your shellcode verbatim into a string like so: auto str = import("shellcode.txt");

I would like to talk about this for a bit. Personally, I think D's system programming abilities are only half-way there. Note that I am not talking about use cases in high-level application code, but rather low-level, widely-used framework code, where every bit of performance matters (for example: memory copy routines, string builders, garbage collectors).

In-line assembler as part of the language is certainly neat, and in fact coming from Delphi to C++ I was surprised to learn that C++ implementations adopted different syntax for asm blocks. However, compared to some C++ compilers, it has severe limitations and is D's only trick in this alley.

For one thing, there is no way to force the compiler to inline a function (like __forceinline / __attribute((always_inline)) ). This is fine for high-level code (where users are best left with PGO and "the compiler knows best"), but sucks if you need a guarantee that the function must be inlined. The guarantee isn't just about inlining heuristics, but also implementation capabilities. For example, some implementations might not be able to inline functions that use certain language features, and your code's performance could demand that such a short function must be inlined. One example of this is inlining functions containing asm blocks - IIRC DMD does not support this. The compiler should fail the build if it can't inline a function tagged with @forceinline, instead of shrugging it off and failing silently, forcing users to check the disassembly every time.

You may have noticed that GCC has some ridiculously complicated assembler facilities. However, they also open the way to the possibilities of writing optimal code - for example, creating custom calling conventions, or inlining assembler functions without restricting the caller's register allocation with a predetermined calling convention. In contrast, DMD is very conservative when it comes to mixing D and assembler. One time I found that putting an asm block in a function turned what were single instructions into blocks of 6 instructions each.

D's lacking in this area makes it impossible to create language features that are on the level of D's compiler built-ins. For example, I have tested three memcpy implementations recently, but none of them could beat DMD's standard array slice copy (despite that in release mode it compiles to a simple memcpy call). Why? Because the overhead of using a custom memcpy routine negated its performance gains.

This might have been alleviated with the presence of sane macros, but no such luck. String mixins are not the answer: trying to translate macro-heavy C code to D using string mixins is string escape hell, and we're back to the level of shell scripts.

We've discussed this topic on IRC recently. From what I understood, Andrei thinks improvements in this area are not "impactful" enough, which I find worrisome.

Personally, I don't think D qualifies as a true "system programming language" in light of the above. It's more of a compiled language with pointers and assembler. Before you disagree with any of the above, first (for starters) I'd like to invite you to translate Daniel Vik's C memcpy implementation to D: http://www.danielvik.com/2010/02/fast-memcpy-in-c.html . It doesn't even use inline assembler or compiler intrinsics.