Implicit integer casting
bearophile
bearophileHUGS at lycos.com
Sun Mar 18 19:30:29 PDT 2012
Andrej Mitrovic:
> Another classic which fails to compile is:
>
> import std.random;
> ubyte c = uniform(0, 256);
It's legit to ask a compiler to help in this case. But currently
the D type system can't help you here.
The D syntax and type system tell apart sharply run-time values
from compile-time ones. And the type system doesn't work on
run-time values.
This is another very simple case that currently the D compilers
and D language don't signal as error at compile-time (a decent C
lint is able to find a similar bug at compile time, if you use
malloc/calloc to allocate the buffer a):
void main() {
int[] a = new int[5];
a[10] = 1;
}
So to do that in D you currently need to create a different
uniform function that accepts compile-time values. If correctly
implemented this doesn't need a cast to compile:
ubyte c = uniformCT!(0, 256)();
There are some ways to improve this situation. One way is to
introduce ranged numerical values (like the Ada ones) in the D
language. This is why implementing them in library code isn't
good enough. With them you are able to tell the type system that
a value is in an arbitrarily compile-time-defined range, and
later the type system is able to use this information for all
kind of things.
Another harder way to improve the situation is to offer the D
programmer some way to tell if a regular argument of a regular
function is known at compile-time (like it being a literal). If
you use this feature inside a regular function, this function
essentially becomes a template :-)
In GCC-C there is something related, named
__builtin_constant_p(exp):
http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
(If you improve that idea you obtain a handmade poor's man
version of partial compilation, that is useful in a system
language.)
I think Walter tried a bit to do a simpler version of this, with
this syntax:
void foo(int x, static int y) {}
Here x is a run-time value and y most be known at compile-time,
so it's similar to (but this conversion doesn't work if y is an
array, I never understood why D templates refuse arrays are
compile-time arguments yet they accept all kind of strings,
despite strings are a subset of dynamic arrays. And alias
argument are not the same thing):
void foo(int y)(int x) {}
One difference here is that this template syntax is not
transparent at the calling point, you must use the template
instantiation syntax:
foo!(5)(n)
Bye,
bearophile
More information about the Digitalmars-d
mailing list