| Thread overview | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 18, 2007 supporting DMD-1.016 and DMD-2.000 with the same source code | ||||
|---|---|---|---|---|
| ||||
Attachments: |
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
| |||
June 18, 2007 Re: supporting DMD-1.016 and DMD-2.000 with the same source code | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Thomas Kuehne | Great tips thank you. These deserve a place on a website and a link from digitalmars imho. | |||
June 18, 2007 Re: supporting DMD-1.016 and DMD-2.000 with the same source code | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Thomas Kuehne | Thomas Kuehne wrote:
>
> 4) class invariants
> ===================
>
> This is the only real trouble spot so far. DMD-1 uses
> invariant{ ... assert(...); ... }
> however DMD-2 uses
> invariant(){ ... assert(...); ... }
Well that's unfortunate. I don't suppose unittest has gotten parenthesis as well?
Sean
| |||
June 18, 2007 Re: supporting DMD-1.016 and DMD-2.000 with the same source code | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly |
Sean Kelly wrote:
> Thomas Kuehne wrote:
>>
>> 4) class invariants
>> ===================
>>
>> This is the only real trouble spot so far. DMD-1 uses
>> invariant{ ... assert(...); ... }
>> however DMD-2 uses
>> invariant(){ ... assert(...); ... }
>
> Well that's unfortunate. I don't suppose unittest has gotten parenthesis as well?
>
>
> Sean
I suspect this is because invariant is now a declaration, a storage class *and* a type constructor.
-- Daniel
| |||
June 18, 2007 Re: supporting DMD-1.016 and DMD-2.000 with the same source code | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | Daniel Keep wrote:
>
> Sean Kelly wrote:
>> Thomas Kuehne wrote:
>>> 4) class invariants
>>> ===================
>>>
>>> This is the only real trouble spot so far. DMD-1 uses
>>> invariant{ ... assert(...); ... }
>>> however DMD-2 uses
>>> invariant(){ ... assert(...); ... }
>> Well that's unfortunate. I don't suppose unittest has gotten
>> parenthesis as well?
>>
>
> I suspect this is because invariant is now a declaration, a storage
> class *and* a type constructor.
Well sure. But adding parens breaks consistency with other similar blocks.
Sean
| |||
June 18, 2007 Re: supporting DMD-1.016 and DMD-2.000 with the same source code | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | Am Mon, 18 Jun 2007 07:57:05 -0700 schrieb Sean Kelly <sean@f4.ca>: > Well sure. But adding parens breaks consistency with other similar blocks. What I find more confusing is the "overloading" of keywords with different meanings or even worse *similar* meanings, especially for programmers that down "grow with the language" like most readers of this NG but will start using it at some point in the future. They have to learn a lot of things in order to use a keyword correctly. Henning -- GPG Public Key: http://keyserver.ganneff.de:11371/pks/lookup?op=get&search=0xDDD6D36D41911851 Fingerprint: 344F 4072 F038 BB9E B35D E6AB DDD6 D36D 4191 1851 | |||
June 18, 2007 Re: supporting DMD-1.016 and DMD-2.000 with the same source code | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Thomas Kuehne | Thomas Kuehne escribió: > 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); > # } > # } > To avoid this ugly hack, how about supporting invariant(){} in Dv1? -- Carlos Santander Bernal | |||
June 18, 2007 Re: supporting DMD-1.016 and DMD-2.000 with the same source code | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Thomas Kuehne | Thomas Kuehne wrote: > 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; > # } It's obvious I need to put together a predefined compiler version. > 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"; > # } > # } This is why I put the string aliases into dmd 1.016. Then, just replace the char[] with string, and it'll work with both 1.0 and 2.0. > > 4) class invariants > =================== > > This is the only real trouble spot so far. DMD-1 uses > invariant{ ... assert(...); ... } > however DMD-2 uses > invariant(){ ... assert(...); ... } I fixed the 1.015 compiler to accept the () as being optional. So, use the () for both, and it should work. > > 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. I find that doing a mechanical global search/replace of char[] with string will successfully convert 95+% of the code, with a little touchup here and there. > > > 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. Hmm, I like the stringz alias. Or maybe cstring? > > > 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. | |||
June 18, 2007 Re: supporting DMD-1.016 and DMD-2.000 with the same source code | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | Daniel Keep wrote: > I suspect this is because invariant is now a declaration, a storage > class *and* a type constructor. It's a dessert topping *and* a floor wax! http://www.jibjab.com/view/101069# | |||
June 19, 2007 Re: supporting DMD-1.016 and DMD-2.000 with the same source code | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Thomas Kuehne | Thomas Kuehne wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> -----BEGIN PGP SIGNATURE-----
> -----END PGP SIGNATURE-----
<snip lots of amazing D future info>
I hope I'm not the only one who's looking at this in amazement. Have I grossly skipped something fundamentally obvious in this NG, or is it that some info about future improvements are distributed through channels other than this NG?
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply