Community

Appendices

Books

htod

While D is binary compatible with C code, it cannot
compile C code nor C header files. In order for
D to link with C code, the C declarations residing
in C header files need to be converted to a D
module. htod is a migration tool to aid in
convering C header files.

htod is built from the front end of the Digital
Mars C and C++ compiler. It works just like a C or
C++ compiler except that its output is a D module
rather than object code.

The macro __HTOD__ is predefined and set to 1,
which is handy for improving C header files to give better
D output.

By default, htod will insert the C and C++ declarations
in a file into the output file prefixed by //C .
-hc will suppress this.
Use only if you're confident that htod is generating the
correct output file (such as if the header file was modified with
__HTOD__).

-hi

By default, htod will represent a #include "file" with
a corresponding import statement. The -hi will cause the
declarations in the included file to be converted to D declarations as
well. The declarations in all included files are parsed regardless.
-hi is handy when replacing an entire hierarchy of include files
with a single D import.
System includes like #include <file> are not affected
by -hi.
See also -hs.

-ht

By default, htod will write types using typedef names as
using those names. -ht will cause the underlying types to be
used instead. This is very useful for "drilling down" layers of
macros, typedefs, and #includes to find out the underlying type.

-hs

Works just like -hi, except that system includes are
migrated as well.

Type Mappings

C types are mapped as follows. These mappings are correct
for Digital Mars C/C++, but may not be correct for your
C compiler. D basic types have fixed sizes, while C basic
type sizes are implementation defined.

Mapping C to D types

C type

D type

void

void

_Bool

bool

wchar_t

wchar

char

char

signed char

byte

unsigned char

ubyte

short

short

unsigned short

ushort

int

int

unsigned

uint

long

int

unsigned long

uint

long long

long

unsigned long long

ulong

float

float

double

double

long double

real

_Imaginary float

ifloat

_Imaginary double

idouble

_Imaginary long double

ireal

_Complex float

cfloat

_Complex double

cdouble

_Complex long double

creal

Limitations

There is no one to one correspondence of C declarations
to D declarations. A review of the D module output will
be necessary to ensure the right decisions are made.
Furthermore:

Whereever
practical, C headers should be written using typedef's and
enum's rather than macros.
htod will attempt to convert simple macro #define's
to alias and const declarations.
Even so, macros are fully expanded before further analysis.

No attempt is made to convert C conditional compilation
into D version or static if declarations.

No output is generated for false conditional compilation
sections.

htod converts declarations only, it does not convert
C code.

Declarations with C++ linkage cannot be converted.
A C interface must be made for any C++ code.

C language extensions present in the C .h file
may not be recognized.

Pragmas are not translated.

The tag names are assumed to not collide with
names in the regular name space.

Any character data that is not ASCII will need
to be converted as necessary to UTF.

The C char type is assumed to map to the
D char type. However, these should be examined individually
to see if they should instead be translated to byte or
ubyte types. Whether the C char type is signed or
unsigned is implementation defined. The D char type
is unsigned.

Named C enum members are not inserted into the surrounding
scope as they are in C.

D modules are each in their own name space, but C
header files are all in the same global name space. This means
that D references to names defined in other modules may
need to be qualified.

Bugs

Anything other than the default struct member
alignment is not accounted for.