Calling printf()
This mostly means checking that the printf format specifier matches the corresponding D data type. Although printf is designed to handle 0 terminated strings, not D dynamic arrays of chars, it turns out that since D dynamic arrays are a length followed by a pointer to the data, the %.*s format works perfectly:
void foo(char[] string)
{
printf("my string is: %.*s\n", string);
}
Astute readers will notice that the printf format string literal in the example doesn't end with \0. This is because string literals, when they are not part of an initializer to a larger data structure, have a \0 character helpfully stored after the end of them.
Structs and Unions
D structs and unions are analogous to C's.
C code often adjusts the alignment and packing of struct members with a command line switch or with various implementation specific #pragma's. D supports explicit alignment attributes that correspond to the C compiler's rules. Check what alignment the C code is using, and explicitly set it for the D struct declaration.
D does not support bit fields. If needed, they can be emulated with shift and mask operations.
Interfacing to C++
D does not provide an interface to C++. Since D, however, interfaces directly to C, it can interface directly to C++ code if it is declared as having C linkage.
D class objects are incompatible with C++ class objects.
Portability Guide
It's good software engineering practice to minimize gratuitous portability problems in the code. Techniques to minimize potential portability problems are:
-
The integral and floating type sizes should be considered as minimums. Algorithms should be designed to continue to work properly if the type size increases.
-
The wchar type can be either 2 or 4 bytes wide in current implementations; future implementations can increase the size further.
-
Floating point computations can be carried out at a higher precision than the size of the floating point variable can hold. Floating point algorithms should continue to work properly if precision is arbitrarilly increased.
-
Avoid depending on the order of side effects in a computation that may get reordered by the compiler. For example:
-
a + b + c
can be evaluated as (a + b) + c, a + (b + c), (a + c) + b, (c + b) + a, etc. Parenthesis control operator precedence, parenthesis do not control order of evaluation.
In particular, function parameters can be evaluated either left to right or right to left, depending on the particular calling conventions used.
-
Avoid dependence on byte order; i.e. whether the CPU is big-endian or little-endian.
-
Avoid dependence on the size of a pointer or reference being the same size as a particular integral type.
-
If size dependencies are inevitable, put an assert in the code to verify it:
-
assert(int.size == (int*).size);
OS Specific Code
System specific code is handled by isolating the differences into separate modules. At compile time, the correct system specific module is imported.
Minor differences can be handled by constant defined in a system specific import, and then using that constant in an if statement.
Embedding D in HTML
The D compiler is designed to be able to extract and compile D code embedded within HTML files. This capability means that D code can be written to be displayed within a browser utilizing the full formatting and display capability of HTML.
For example, it is possible to make all uses of a class name actually be hyperlinks to where the class is defined. There's nothing new to learn for the person browsing the code, he just uses the normal features of an HTML browser. Strings can be displayed in green, comments in red, and keywords in boldface, for one possibility. It is even possible to embed pictures in the code, as normal HTML image tags.
Embedding D in HTML makes it possible to put the documentation for code and the code itself all together in one file. It is no longer necessary to relegate documentation in comments, to be extracted later by a tech writer. The code and the documentation for it can be maintained simultaneously, with no duplication of effort.
How it works is straightforward. If the source file to the compiler ends in .htm or .html, the code is assumed to be embedded in HTML. The source is then preprocessed by stripping all text outside of and tags. Then, all other HTML tags are stripped, and embedded character encodings are converted to ASCII. All newlines in the original HTML remain in their corresponding positions in the preprocessed text, so the debug line numbers remain consistent. The resulting text is then fed to the D compiler.
Here's an example of the D program "hello world" embedded in this very HTML file. This file can be compiled and run.
import Object;
import stdio;
int main()
{
printf("hello world\n");
return 0;
}
D Runtime Model Object Model
An object consists of:
offset contents
------ --------
0: pointer to vtable
4: monitor
8... non-static members
The vtable consists of:
0: pointer to instance of ClassLayout
4... pointers to virtual member functions
Array Model
A dynamic array consists of:
0: pointer to array data
4: array dimension
A dynamic array is declared as:
type array[];
whereas a static array is declared as:
type array[dimension];
Thus, a static array always has the dimension statically available as part of the type, and
so it is implemented like in C. Static array's and Dynamic arrays can be easilly converted back
and forth to each other.
Reference Types
---------------
D has reference types, but they are implicit. For example, classes are always
referred to by reference; this means that class instances can never reside on the stack
or be passed as function parameters.
When passing a static array to a function, the result, although declared as a static array, will
actually be a reference to a static array. For example:
int abc[3];
Passing abc to functions results in these implicit conversions:
void func(int array[3]); // actually
void func(int *p); // abc[3] is converted to a pointer to the first element
void func(int array[]); // abc[3] is converted to a dynamic array
Class Model
-----------
The class definition:
class XXXX
{
....
};
Generates the following:
o An instance of Class called ClassXXXX.
o A type called StaticClassXXXX which defines all the static members.
o An instance of StaticClassXXXX called StaticXXXX for the static members.
Share with your friends: |