supporting DMD-1.016 and DMD-2.000 with the same source code

Thomas Kuehne thomas-dloop at kuehne.cn
Mon Jun 18 06:57:22 PDT 2007


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1


Below are a few code samples that might help you to make your code
compatible with DMD-1.016 as well as DMD-2.000.


1) What compiler am I running?
==============================

# static if(is(typeof((new char[3]).idup))){
# 	pragma(msg, "DMD version 2");
#   static dmd_version = 2;
# }else{
# 	pragma(msg, "DMD version 1");
#   static dmd_version = 1;
# }

Usually I try to avoid any kind of version detection, however
the class invariant changes (see below) require it this time.
If you are only using Phobos and not alternatives like Tango
the language version can be accessed via:

# import std.compiler : version_major;
# import std.metastrings : ToString;
#
# pragma(msg, "DMD version " ~ ToString!(version_major));
# alias version_major dmd_version;


2) 'string', 'wstring', 'dstring'
=================================

If you defined a 'string' type or alias replace it with myString or
similar. The same is valid for 'wstring' and 'dstring'.


3) Object.toString
==================

In DMD-1 the signature is
	char[] Object.toString();
however in DMD-2 the signature is
	const(char)[] Object.toString();

An ad-hock solution would be:

# class Foo{
#    typeof((new Object()).toString()) toString(){
#       return "abc";
#    }
# }

This solution works reliably but is 'ugly' and doesn't scale
very well. Thus the slightly longer version:

# static if(!is(string)){
#    static if(! is(typeof((new Object()).toString()) string)){
#       alias char[] string;
#    }
# }
#
# class Foo{
#    string toString(){
#       return "abc";
#    }
# }


4) class invariants
===================

This is the only real trouble spot so far. DMD-1 uses
	invariant{ ... assert(...); ... }
however DMD-2 uses
	invariant(){ ... assert(...); ... }

There are basically two approaches. Both require dmd_version from
1) "What compiler am I running?" (see above). First the complete
mixin solution:

# class Foo : Object{
#    int x;
#
#    mixin("invariant" ~ (dmd_version < 2 ? "" : "()") ~
#       "{
#          assert(x < 100);
#       }");
# }

This might be a quick hack however in most cases you are going to
lose nice features like syntax highlighting. Invariants are
prohibited from calling 'public' member function but calling
'private' member functions is OK:

# const char[] invariantCall = "invariant" ~ (dmd_version < 2 ? "" : "()")
#    ~ "{ invariant_(); }";
#
# class Foo : Object{
#    int x;
#
#    mixin(invariantCall);
#
#    private void invariant_(){
#       assert(x < 100);
#    }
# }

5) string functions
===================

Where ever reasonable replace 'char[]' with 'string' (see 3) above).
Due to my general coding style this was basically a search/replace
operation that requires almost no further code changes. In the case of
Flectioned 2 additional ".dup"s were needed.


6) C-strings
============

Sometime I have to interface with C libries this "const char*" is
required:

# static if(1 < dmd_version){
#    mixin("alias const(char)* stringz;");
# }else{
#    alias char* stringz;
# }

The mixin in required because the content has to be syntactically
correct and "const(char)" isn't a valid DMD-1 construct.


7) the 'rest'
=============

Depending on your coding style you might have to deal with 'final'
parameters and 'final' foreach value variables, but in my case 
(3873 lines of cross OS code) not a single change was required.

Thomas

-----BEGIN PGP SIGNATURE-----

iQIVAwUBRnaPP7ZlboUnBhRKAQK46RAAhAOvSpZTtaJ+2OdcLfCkDsJNE/kzQm9A
BK7xVUovXs63uvAGkrOeN5SwRxHhWousdbrYZwAmKrQ9KrEDOZVFON134SEC0IAf
Greg1fYZSXc/g6myWeqGzAXT7OBSQ4EkRTl8lkbTvSO6467ynx88GlATRxsFZ+t6
EHSbqS8M1Gkh3tiXXMQqOBxqmLJujJyS78c4f2pQsvPqYpPgugZsQrpgKseIlH5q
b3v7qji9ACnvZGIMCq5zhrq945J9YvJYQEjqLDs4+SCcgGFzuvLUXTdVlga5MyeI
UmyGDS5fvdDNX35wsKk1St8ZHfxORyI3+FEHeMCxHY5YT1govhkgBqK7suS/Kp6M
ySZsQ9sIpjYwWTIEViflJ9otuY7l/nH1H5OGm2tS+dxDhzLjFw7jCBy/9c0eIxtL
WrXovAv2fVn6MbnkqGs3lBGEj0o518Chc2zHyBQikFUaE8cpdj5PxEP2usnq/WGE
2vQ0fsRUhfnHcV/p9DOyNsQyjBGIBL2BK2sNBDSqkScxVoPE7ZBAHNpsDsQZlUwS
8IlkqAbLPFRJxPBWiR/2dsi6SbM/hg+lfyqOqdzZvNfpICWcXcETab0JEk3WODb0
7EpT9F6CDLpWBvOhxtb/rzTkPpjWdpYg0Q2alT4CgnwjdrYDH1btSxYCPmm/OL23
qi8DHAD+X0o=
=fZxN
-----END PGP SIGNATURE-----



More information about the Digitalmars-d mailing list