D Programming Language 1.0

Last update Sun Dec 30 20:34:43 2012


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.




htod cheader.h [dimport.d] [-cpp] [-hc] [-hi] [-hs] [-ht] { C compiler switches }


C or C++ header input file
D source code output file (defaults to cheader.d)
Indicates a C++ header file
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__).
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.
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.
Works just like -hi, except that system includes are migrated as well.
C compiler switches
C or C++ compiler switches, such as -D and -I as documented for dmc.


The C test.h file:

unsigned u;
#define MYINT int
void bar(int x, long y, long long z);

Translated with:

htod test.h

Produces the file test.d:

/* Converted to D from test.h by htod */
module test;
//C     unsigned u;
extern (C):
uint u;
//C     #define MYINT int
//C     void bar(int x, long y, long long z);
alias int MYINT;
void  bar(int x, int y, long z);

The C declarations are prefixed by the string "//C ".

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


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:

  1. 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.
  2. No attempt is made to convert C conditional compilation into D version or static if declarations.
  3. No output is generated for false conditional compilation sections.
  4. htod converts declarations only, it does not convert C code.
  5. Declarations with C++ linkage cannot be converted. A C interface must be made for any C++ code.
  6. C language extensions present in the C .h file may not be recognized.
  7. Pragmas are not translated.
  8. The tag names are assumed to not collide with names in the regular name space.
  9. Any character data that is not ASCII will need to be converted as necessary to UTF.
  10. 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.
  11. Named C enum members are not inserted into the surrounding scope as they are in C.
  12. 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.


  1. Anything other than the default struct member alignment is not accounted for.
  2. No Linux version.

Forums | Comments |  D  | Search | Downloads | Home