digitalmars.D.learn - Prettiful error messages with templates
- Simen Kjaeraas (43/43) May 04 2008 I'm currently using this somewhat verbose approach to template error =
- Lutger (45/45) May 05 2008 Not sure how this works in D2 and it doesn't solve the biggest problems ...
I'm currently using this somewhat verbose approach to template error =
messages:
debug
{
int opAdd(U, int line =3D __LINE__, string file =3D __FILE__)(U args)=
{
static if (__traits(compiles, somethingHere)) // check if this =
template should have been instantiated at all
{
pragma(msg, "Failed instantiating template in file " ~ file ~ " o=
n =
line " ~ toString(line)); // for a more prettiful error message. Could =
easily put this in the assert
static assert(0);
}
// Do actual work here. Don't use line or file arguments.
}
}
else
{
int opAdd(U)(U args)
{
// Do actual work here.
}
}
Now, what are the problems with this approach?
1. It is rather verbose.
2. Code duplication.
3. Template bloat for the debug version. For every time + is used, a new=
=
instantiation is created. I have duplicated the code to avoid this in =
release builds.
4. toString(int) is not CTFE-compatible.
Good things:
It gives exact error messages, telling the user what went wrong and wher=
e.
So, what do I want?
limitation of the linker or compiler), I could avoid the code duplicatio=
n, =
so I guess that's the biggest problem.
Any ideas?
-- Simen
May 04 2008
Not sure how this works in D2 and it doesn't solve the biggest problems but
here's a possible begin:
char[] assertCompiles(uint line, char[] file, char[] code)
{
return `debug { static if (!__traits(compiles, ` ~ code ~ `))`
`{`
`pragma(msg, "Failed instantiating template in file ` ~ file
~ ` on line ` ~ ctfeToString(line) ~ `");`
`static assert(false);`
`}}`;
}
iirc I adapted ctfeToString from phobos' std.string:
const char[10] digits = "0123456789"; /// 0..9
/// ditto
char[] ctfeToString(ulong u)
{
char[] buffer;
auto buflen = ulong.sizeof * 3;
while (buflen--)
buffer ~= ' ';
int ndigits;
ndigits = 0;
if (u < 10)
// Avoid storage allocation for simple stuff
return digits[u .. u + 1];
else
{
while (u)
{
uint c = (u % 10) + '0';
u /= 10;
ndigits++;
buffer[buffer.length - ndigits] = cast(char)c;
}
return buffer[buffer.length - ndigits .. buffer.length].dup;
}
}
it'll help a bit with the verbosity, used as:
int opAdd(U, uint line = __LINE__, char[] file = __FILE__ ) (U args)
{
mixin( assertCompiles(line, file, code));
...
}
Will you post back when you found some good solutions? Thanks.
Good luck and happy hacking ;)
May 05 2008








Lutger <lutger.blijdestin gmail.com>