Porting tips for D
Thomas Kuehne
thomas-dloop at kuehne.cn
Fri Mar 10 14:39:32 PST 2006
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
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
-----BEGIN PGP SIGNATURE-----
iD8DBQFEEg3Q3w+/yD4P9tIRAicDAKCG767tDXJQt46XfgpoHO2lyLVxVwCfTEFE
6KU4WBC2IiQaOPEsv2u7M+g=
=1zUj
-----END PGP SIGNATURE-----
More information about the Digitalmars-d-learn
mailing list