# Value Preservation and Polysemy -> context dependent integer literals

Fawzi Mohamed fmohamed at mac.com
Fri Dec 5 18:16:03 PST 2008

```On 2008-12-05 16:27:01 +0100, Andrei Alexandrescu
<SeeWebsiteForEmail at erdani.org> said:

> Fawzi Mohamed wrote:
>> On 2008-12-05 07:02:37 +0100, Andrei Alexandrescu
>> <SeeWebsiteForEmail at erdani.org> said:
>>
>>> [...]
>>> Well any integral value carries:
>>>
>>> a) type as per the C rule
>>>
>>> b) minimum value possible
>>>
>>> c) maximum value possible
>>>
>>> The type stays the type as per the C rule, so there's no change there.
>>> If (and only if) a *narrower* type is asked as a conversion target for
>>> the value, the range is consulted. If the range is too large, the
>>> conversion fails.
>>>
>>> Andrei
>>
>> basically the implicit conversion rules of C disallowing automatic
>> unsigned/signed conversions to unsigned?
>> Fawzi
>>
>
> Where's the predicate? I don't understand the question.
>
> Andrei

The implicit conversion rules in C when performing arithmetic
operations allow up-conversion of types, basically the largest type
present is used, which almost already respect a,b,c: (using C names)

1) if long double is present everything is converted to it
2) otherwise if double is present everything is converted to it
3) otherwise if float is present everything is converted to it

if only signed or only unsigned integers are present the are ranked in
the following sequence
char, short, int ,long,long long
and everything is converted to the largest type (largest rank)

If the range of the signed integer include the range of the unsigned
integer everything is copied to the signed type
these rules respect a,b,c

for example
ushort us=1;
printf("%g\n",1.0*(-34+us));
prints -33, as one would expect.

Now the two rules that break this and that you want to abolish (or at
least you have problems with) if I have understood correctly are
* if the signed number has rank<= the unsigned convert to the unsigned
* otherwise the unsigned version of the signed type is used.
Is this correct? did I understand what you mean correctly? this is what
polysemy does?

I agree that in general these two last rules can bring a little bit of
confusion
printf("%g\n",1.0*(-34+1u));
printf("%g\n",1.0*(-34+1UL));
printf("%g\n",1.0*(-34-1u));
prints
4.29497e+09
1.84467e+19
4.29497e+09
but normally it does not matter, because the bit pattern is what one
expects, and casting to the correct type one has the correct result
printf("%g\n",1.0*cast(int)(-34+1u));
printf("%g\n",1.0*cast(long)(-34+1UL));
printf("%g\n",1.0*cast(int)(-34-1u));
prints
-33
-33
-35
and the advantage of combining freely signed and unsigned without cast
(and it happens often)  I think out weights its problems.

The only problem that I have seen connected to this is people thinking
opCmp =	cast(signed)(unsigned-unsigned);
which is wrong.

What I would like to have is
1) adaptive integer literals

For one kind of integer literals, optimally the decimal literals
without prefix, and introducing a prefix for int integer literals (yes
in my first message I proposed the opposite, a prefix for the new kind
of literals, but I changed idea already in the second one) to have a
very lax regime, based of value preservation:
- all calculations of these integer literals between themselves are
done with arbitrary precision
- this literal can implicitly cast to any type as long as the type can
represent the value (that is obviously known at compile time)
- for matching overloaded functions one has to find a rule, this is
something I am not too sure about, int if the vale fits in it, long if
it doesn't and ulong if it does not fit in either could be a
possibility.

2) different integer type for size_t ptr_diff_t (and similar integer
types that have the size of a pointer)

no cast needed between size_t and ptr_diff_t
cast needed between them and both long and int

Fawzi

```

More information about the Digitalmars-d mailing list