# Integer Promotion Weirdness

**URL:** <https://chapel.discourse.group/t/integer-promotion-weirdness/33886>\
**Category:** Users\
**Created:** [June 5, 2024, 1:59am UTC](https://chapel.discourse.group/t/integer-promotion-weirdness/33886 "2024-06-05T01:59:08Z")\
**Posts on this page:** 1\
**Showing post:** 30

<div class="post-metadata">

**Author:** ![damianmoz](https://yyz2.discourse-cdn.com/free1/user_avatar/chapel.discourse.group/damianmoz/32/319_2.png) [@damianmoz](https://chapel.discourse.group/u/damianmoz)\
**Post date:** [December 18, 2025, 10:08pm UTC](https://chapel.discourse.group/t/integer-promotion-weirdness/33886/30 "2025-12-18T22:08:05Z")

</div>

> [@mppf](#):
>
> Indeed at some point during development of the fixes (that resolved the `real` problems for you), we had test failures because `sin(1)` started to return `real(32)` rather than `real(64)`.
> 
> Perhaps it would be more consistent to choose the “smallest type that fits”, but this will lead to casts in such a `sin` case. In other words, it trades casts in your situation for casts in another situation. It does not remove the need for casts

I agree it does not remove the need for casts.

Once you use `the smallest type that fits` for a generic literal, `sin(1)` is obvious. It is very easy to explain. Please remember that `the smallest type that fits` is a **rule of last resort** and it is imperfect for extreme/strange cases. The type of a literal should use context if that context exists. I will note that mathematically, the literal `sin(1)` has infinite precision and is unable to be evaluated on current hardware so I would regard it as an error in my own code. Only `sin(1:uint(w))` for some _w_ has finite precision.

I cannot explain why adding 42 to a 32-bit integer suddenly delivers a 64-bit integer without saying that Chapel has no such thing as a true literal.

> [@mppf](#):
>
> In theory, we could have the type system separate an “untyped” or “default” literal from a typed one, so that `1:int(64)` and `1` have different types. Even if we got it to work, it would be a pretty big development effort and a breaking change.

The digit `1` is a literal. The typed value `1:int(64)` is an anonymous **param**.

And yes, it is a breaking change but it is already broken for anybody trying to port existing code. Although it is not a breaking change if you have a compiler options like

```Chapel
--[no]default-literal-size

```

where ``--default-literal-size` is the default.

I would argue that Chapel is already broken because the expressions

```chapel
param t = .<some 32-bit literal>
const s = <some 32-bit literal where t == s>
....
param x = t + 42;
const y = s + 42;

```

do not deliver the same overall result even though`t == s`. Overall result means more than just the numeric value. How do I explain that to novice programmers?

Getting back to readability:

```chapel
param x = t + 42:t.type

```

is still ugly. I still cannot see why adding 42 to a 32-bit integer should deliver anything other than a 32-bit integer. In the expression

```chapel
t + 42

```

The only type-related information provided by the programmer is the type of `x` so the compiler should not presume anything else.

I am not a big fan of any Chapel code that uses a declaration with a naked **int** or **real**.

I apologize for raising something that means work. But the Chapel concept of default sizes for those types and the handling of literals is going to cause more grief for **int** (128) and **real** (128) so I would argue that the issue needs to be addressed rather than later irrespective of the grief it is already causing me and others in porting existing code.

The concept of `smallest type that fits` is not mine.

P.S. If an integer literal has type **int** (256), i.e. beyond supported sizes, when it comes to using them in contextual expressions with objects of type **int** (_w_), you use a precedence of `w % 256` for everything and then rely on the rules to promote the literal as appropriate. Then again, I have not worked on serious compiler internals for 24 years so I could be wrong.

Thanks again for your time Michael.

---

_[View the full topic](https://chapel.discourse.group/t/integer-promotion-weirdness/33886)._
