Boost logo

Boost :

From: Maciej Sobczak (prog_at_[hidden])
Date: 2004-04-05 07:49:29


Hi,

Brian Martin wrote:

> Brian Martin wrote:
>
>>I'll have another think about some of the compile time check issues.
>
>
> I have and have done the following:
>
> 1) Compile time checks would be nice but are basically impossible. At least the ones that count. Such as:
>
> subrange<int, 1, 20> sub_20(30); or sub_20 = 300;
>
> Pascal traps this kind of thing but C++ can't, as far as I can see. Runtime only, I'm afraid.

One could also try to do:

subrange<int, 1, 20> sub_20 = literal<int, 20>();
sub_20 = literal<int, 300>(); // should not compile with compile-time checks

where literal can be as simple as:

template <typename T, T N> struct literal {};

+ a couple of overloads in the subrange class.

> I am of the opinion that the compile time checks that were given in Maciej's example code are of limited use since the real benefit of subranges is runtime (in my humble opinion).

It all depends on what you want to achieve.
Compile-time checks allow you to *avoid* any checking at run-time, thus
making the whole subrange class (or however you call it) potentially the
same efficient as the raw fundamental types. Most of the optimizers are
able to:
1. inline simple function calls and
2. eliminate unused code, including creation and destruction of unused
local objects

With both of these optimizations in hand, the following code:

s1 = s2 + s3;

can be potentially reduced to a few machine instructions, just as if s1,
s2 and s3 were just ints or longs or whatever.
I think that the range class should not impose any cost (runtime-check)
in the places where it can be proved that such cost can be avoided.

The second advantage of using compile-time checks is to find places that
will for sure break the code, for example where source and destination
ranges do not overlap. There is no reason to let such code compile,
because it may form the execution path that you will never be able to
test by yourself and your will get the error at your most important
presentation. As usual in such cases.

In places where compile-time checks cannot be made, run-time checks
(possibly followed by exceptions) are used. This includes assignments
from rvalues of fundamental type.

This is the most optimal solution in my opinion.

> 3) I've used a conversion operator.

Me too but removed it. It broke (introduced ambiguities) other
overloaded operators. Try to write some more complicated expression
involving both ranges and fundamental types, function calls, etc.
This is a good test.

> 4) Removed operator~().

I resigned from other bitwise operators (including shifts) as well.

-- 
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk