March 10, 2006 Porting tips for D | ||||
---|---|---|---|---|
| ||||
Attachments: | Background: I'm currently merging GDC-0.18.1 and GPhobos64 === 1: auto === Use "auto" when ever reasonable possible, doing so usually decreases the porting costs. # # auto x = someObject.foo(); # instead of # # uint x = someObject.foo(); # === 2: size_t / prtdiff_t === Unless you require specific bit sizes use size_t(unsigned) and ptrdiff_t(signed) for temporary integers - doing so reduces the risk of truncated array.length and can result in speedups. Use std.stdint for special needs. === 3: length === Length is usually an unsigned integer. # # size_t len = anotherObject.length(); # instead of # # ptrdiff_t len = anotherObject.length(); # The difference between unsigned and signed might not be noticeable when using "normal" length, but will be in corner cases. === 4: cast and auto/typeof === Consider the use of "typeof" or "auto" if you are sure you have to use a cast. # auto x = cast(some_type) y; # # z = cast(typeof(z)) y; instead of # /* valid but likely typos */ # type_a x = cast(type_b) y; # type_c z; # z = cast(type_d) y; === 5: static if / assert === "static if", "pragma(msg, ...)" and "static assert" are there for a reason - use them to document and ensure that basic assumptions of your implementation are valid at compile time. e.g.: # static if(real.max < double.max || real.dig < double.dig){ # double someFloat; # }else{ # real someFloat; # } === 6: unittest / invariant / in,out,body === Use unittest and invariants to test the sanity of your implementation at runtime. === 7: version - else === Safeguard your version expressions. # version(Windows){ # import windows_module; # }else version(linux){ # import linux_module; # }else{ # pragma(msg, "unsupported OS"); # static assert(0); # } instead of # version(Windows){ # import windows_module; # } # version(linux){ # import linux_module; # } The second sample can lead to hard to track down bugs. === 8: version(X86 / AMD64 / ...) === You are usually not interested what CPU is used but what the size of a pointer or "native int" is. # static if(size_t.sizeof == 4){ # // 32bit system # }else static if(size_t.sizeof == 8){ # // 64bit system # }else{ # // something other # } or # static if((void*).sizeof == 4){ # // 32bit system # }else static if((void*).sizeof == 8){ # // 64bit system # }else{ # // something other # } instead of # version(X86){ # }else version(AMD64){ # }else{ # } === 9: _argptr / va_arg!() === Don't access _argptr directly but use std.stdarg.va_arg to shield your code from the stack layouts of different architectures. === 10: trivia === This might sound trivial: 1) Use the right tool for your problem, don't try to find a problem description that fits your tool (except for educational/comparative purposes). Yes, D might not be the best tool to solve your problem. 2) Design, documentation and testing(unittests, invariants, test suite) don't matter - until maintenance kicks in. Thomas |
Copyright © 1999-2021 by the D Language Foundation